Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: sync/engine/sync_scheduler_unittest.cc

Issue 124083002: Client-side changes to support retry GU. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/bind.h" 5 #include "base/bind.h"
6 #include "base/callback.h" 6 #include "base/callback.h"
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/memory/weak_ptr.h" 8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/test/test_timeouts.h" 10 #include "base/test/test_timeouts.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 public: 44 public:
45 MockSyncer(); 45 MockSyncer();
46 MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet, 46 MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet,
47 const sessions::NudgeTracker&, 47 const sessions::NudgeTracker&,
48 sessions::SyncSession*)); 48 sessions::SyncSession*));
49 MOCK_METHOD3(ConfigureSyncShare, 49 MOCK_METHOD3(ConfigureSyncShare,
50 bool(ModelTypeSet, 50 bool(ModelTypeSet,
51 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource, 51 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource,
52 SyncSession*)); 52 SyncSession*));
53 MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, sessions::SyncSession*)); 53 MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, sessions::SyncSession*));
54 MOCK_METHOD2(RetrySyncShare, bool(ModelTypeSet, sessions::SyncSession*));
54 }; 55 };
55 56
56 MockSyncer::MockSyncer() 57 MockSyncer::MockSyncer()
57 : Syncer(NULL) {} 58 : Syncer(NULL) {}
58 59
59 typedef std::vector<TimeTicks> SyncShareTimes; 60 typedef std::vector<TimeTicks> SyncShareTimes;
60 61
61 void QuitLoopNow() { 62 void QuitLoopNow() {
62 // We use QuitNow() instead of Quit() as the latter may get stalled 63 // We use QuitNow() instead of Quit() as the latter may get stalled
63 // indefinitely in the presence of repeated timers with low delays 64 // indefinitely in the presence of repeated timers with low delays
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 RecordSyncShare(&times2))); 539 RecordSyncShare(&times2)));
539 scheduler()->ScheduleInvalidationNudge(zero(), invalidations2, FROM_HERE); 540 scheduler()->ScheduleInvalidationNudge(zero(), invalidations2, FROM_HERE);
540 RunLoop(); 541 RunLoop();
541 } 542 }
542 543
543 // Test that polling works as expected. 544 // Test that polling works as expected.
544 TEST_F(SyncSchedulerTest, Polling) { 545 TEST_F(SyncSchedulerTest, Polling) {
545 SyncShareTimes times; 546 SyncShareTimes times;
546 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); 547 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
547 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) 548 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
548 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), 549 .WillRepeatedly(
549 RecordSyncShareMultiple(&times, kMinNumSamples))); 550 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
551 RecordSyncShareMultiple(&times, kMinNumSamples)));
550 552
551 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); 553 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval);
552 554
553 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; 555 TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
554 StartSyncScheduler(SyncScheduler::NORMAL_MODE); 556 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
555 557
556 // Run again to wait for polling. 558 // Run again to wait for polling.
557 RunLoop(); 559 RunLoop();
558 560
559 StopSyncScheduler(); 561 StopSyncScheduler();
560 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); 562 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval);
561 } 563 }
562 564
563 // Test that the short poll interval is used. 565 // Test that the short poll interval is used.
564 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) { 566 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) {
565 SyncShareTimes times; 567 SyncShareTimes times;
566 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); 568 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
567 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) 569 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
568 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), 570 .WillRepeatedly(
569 RecordSyncShareMultiple(&times, kMinNumSamples))); 571 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
572 RecordSyncShareMultiple(&times, kMinNumSamples)));
570 573
571 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval); 574 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval);
572 scheduler()->SetNotificationsEnabled(false); 575 scheduler()->SetNotificationsEnabled(false);
573 576
574 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; 577 TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
575 StartSyncScheduler(SyncScheduler::NORMAL_MODE); 578 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
576 579
577 // Run again to wait for polling. 580 // Run again to wait for polling.
578 RunLoop(); 581 RunLoop();
579 582
580 StopSyncScheduler(); 583 StopSyncScheduler();
581 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); 584 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval);
582 } 585 }
583 586
584 // Test that polling intervals are updated when needed. 587 // Test that polling intervals are updated when needed.
585 TEST_F(SyncSchedulerTest, PollIntervalUpdate) { 588 TEST_F(SyncSchedulerTest, PollIntervalUpdate) {
586 SyncShareTimes times; 589 SyncShareTimes times;
587 TimeDelta poll1(TimeDelta::FromMilliseconds(120)); 590 TimeDelta poll1(TimeDelta::FromMilliseconds(120));
588 TimeDelta poll2(TimeDelta::FromMilliseconds(30)); 591 TimeDelta poll2(TimeDelta::FromMilliseconds(30));
589 scheduler()->OnReceivedLongPollIntervalUpdate(poll1); 592 scheduler()->OnReceivedLongPollIntervalUpdate(poll1);
590 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) 593 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
591 .WillOnce(DoAll( 594 .WillOnce(DoAll(
592 WithArgs<0,1>( 595 WithArgs<0,1>(
593 sessions::test_util::SimulatePollIntervalUpdate(poll2)), 596 sessions::test_util::SimulatePollIntervalUpdate(poll2)),
594 Return(true))) 597 Return(true)))
595 .WillRepeatedly( 598 .WillRepeatedly(
596 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), 599 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
597 WithArg<1>( 600 WithArg<1>(
598 RecordSyncShareMultiple(&times, kMinNumSamples)))); 601 RecordSyncShareMultiple(&times, kMinNumSamples))));
599 602
600 TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2; 603 TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2;
601 StartSyncScheduler(SyncScheduler::NORMAL_MODE); 604 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
602 605
603 // Run again to wait for polling. 606 // Run again to wait for polling.
604 RunLoop(); 607 RunLoop();
605 608
606 StopSyncScheduler(); 609 StopSyncScheduler();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); 680 TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
678 scheduler()->OnReceivedLongPollIntervalUpdate(poll); 681 scheduler()->OnReceivedLongPollIntervalUpdate(poll);
679 682
680 ::testing::InSequence seq; 683 ::testing::InSequence seq;
681 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) 684 EXPECT_CALL(*syncer(), PollSyncShare(_,_))
682 .WillOnce(DoAll( 685 .WillOnce(DoAll(
683 WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)), 686 WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)),
684 Return(true))) 687 Return(true)))
685 .RetiresOnSaturation(); 688 .RetiresOnSaturation();
686 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) 689 EXPECT_CALL(*syncer(), PollSyncShare(_,_))
687 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), 690 .WillRepeatedly(
688 RecordSyncShareMultiple(&times, kMinNumSamples))); 691 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
692 RecordSyncShareMultiple(&times, kMinNumSamples)));
689 693
690 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1; 694 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1;
691 StartSyncScheduler(SyncScheduler::NORMAL_MODE); 695 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
692 696
693 // Run again to wait for polling. 697 // Run again to wait for polling.
694 RunLoop(); 698 RunLoop();
695 699
696 StopSyncScheduler(); 700 StopSyncScheduler();
697 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll); 701 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll);
698 } 702 }
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 RecordSyncShare(&times))); 1114 RecordSyncShare(&times)));
1111 RunLoop(); 1115 RunLoop();
1112 Mock::VerifyAndClearExpectations(syncer()); 1116 Mock::VerifyAndClearExpectations(syncer());
1113 optimal_job_time = optimal_job_time + backoff; 1117 optimal_job_time = optimal_job_time + backoff;
1114 ASSERT_EQ(2U, times.size()); 1118 ASSERT_EQ(2U, times.size());
1115 EXPECT_GE(times[1], optimal_job_time); 1119 EXPECT_GE(times[1], optimal_job_time);
1116 1120
1117 // Now let the Poll timer do its thing. 1121 // Now let the Poll timer do its thing.
1118 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) 1122 EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1119 .WillRepeatedly(DoAll( 1123 .WillRepeatedly(DoAll(
1120 Invoke(sessions::test_util::SimulatePollSuccess), 1124 Invoke(sessions::test_util::SimulatePollRetrySuccess),
1121 RecordSyncShareMultiple(&times, kMinNumSamples))); 1125 RecordSyncShareMultiple(&times, kMinNumSamples)));
1122 RunLoop(); 1126 RunLoop();
1123 Mock::VerifyAndClearExpectations(syncer()); 1127 Mock::VerifyAndClearExpectations(syncer());
1124 ASSERT_EQ(kMinNumSamples, times.size()); 1128 ASSERT_EQ(kMinNumSamples, times.size());
1125 for (size_t i = 2; i < times.size(); i++) { 1129 for (size_t i = 2; i < times.size(); i++) {
1126 optimal_job_time = optimal_job_time + poll; 1130 optimal_job_time = optimal_job_time + poll;
1127 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); 1131 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
1128 EXPECT_GE(times[i], optimal_job_time); 1132 EXPECT_GE(times[i], optimal_job_time);
1129 } 1133 }
1130 1134
1131 StopSyncScheduler(); 1135 StopSyncScheduler();
1132 } 1136 }
1133 1137
1134 // Test that poll failures are ignored. They should have no effect on 1138 // Test that poll failures are ignored. They should have no effect on
1135 // subsequent poll attempts, nor should they trigger a backoff/retry. 1139 // subsequent poll attempts, nor should they trigger a backoff/retry.
1136 TEST_F(SyncSchedulerTest, TransientPollFailure) { 1140 TEST_F(SyncSchedulerTest, TransientPollFailure) {
1137 SyncShareTimes times; 1141 SyncShareTimes times;
1138 const TimeDelta poll_interval(TimeDelta::FromMilliseconds(1)); 1142 const TimeDelta poll_interval(TimeDelta::FromMilliseconds(1));
1139 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); 1143 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval);
1140 UseMockDelayProvider(); // Will cause test failure if backoff is initiated. 1144 UseMockDelayProvider(); // Will cause test failure if backoff is initiated.
1141 1145
1142 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) 1146 EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1143 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollFailed), 1147 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollRetryFailed),
1144 RecordSyncShare(&times))) 1148 RecordSyncShare(&times)))
1145 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), 1149 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
1146 RecordSyncShare(&times))); 1150 RecordSyncShare(&times)));
1147 1151
1148 StartSyncScheduler(SyncScheduler::NORMAL_MODE); 1152 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
1149 1153
1150 // Run the unsucessful poll. The failed poll should not trigger backoff. 1154 // Run the unsucessful poll. The failed poll should not trigger backoff.
1151 RunLoop(); 1155 RunLoop();
1152 EXPECT_FALSE(scheduler()->IsBackingOff()); 1156 EXPECT_FALSE(scheduler()->IsBackingOff());
1153 1157
1154 // Run the successful poll. 1158 // Run the successful poll.
1155 RunLoop(); 1159 RunLoop();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. 1272 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry.
1269 } 1273 }
1270 1274
1271 TEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) { 1275 TEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) {
1272 SyncShareTimes times; 1276 SyncShareTimes times;
1273 TimeDelta poll(TimeDelta::FromMilliseconds(15)); 1277 TimeDelta poll(TimeDelta::FromMilliseconds(15));
1274 scheduler()->OnReceivedLongPollIntervalUpdate(poll); 1278 scheduler()->OnReceivedLongPollIntervalUpdate(poll);
1275 1279
1276 ::testing::InSequence seq; 1280 ::testing::InSequence seq;
1277 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) 1281 EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1278 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), 1282 .WillRepeatedly(
1279 RecordSyncShareMultiple(&times, kMinNumSamples))); 1283 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
1284 RecordSyncShareMultiple(&times, kMinNumSamples)));
1280 1285
1281 connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR); 1286 connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR);
1282 StartSyncScheduler(SyncScheduler::NORMAL_MODE); 1287 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
1283 1288
1284 // Run to wait for polling. 1289 // Run to wait for polling.
1285 RunLoop(); 1290 RunLoop();
1286 1291
1287 // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll, 1292 // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll,
1288 // but after poll finished with auth error from poll timer it should retry 1293 // but after poll finished with auth error from poll timer it should retry
1289 // poll once more 1294 // poll once more
1290 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) 1295 EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1291 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), 1296 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
1292 RecordSyncShare(&times))); 1297 RecordSyncShare(&times)));
1293 scheduler()->OnCredentialsUpdated(); 1298 scheduler()->OnCredentialsUpdated();
1294 connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK); 1299 connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK);
1295 RunLoop(); 1300 RunLoop();
1296 StopSyncScheduler(); 1301 StopSyncScheduler();
1297 } 1302 }
1298 1303
1304 TEST_F(SyncSchedulerTest, SuccessfulRetry) {
1305 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
1306
1307 SyncShareTimes times;
1308 base::TimeTicks t1 = base::TimeTicks::Now();
1309 scheduler()->OnReceivedGuRetryDelaySeconds(1);
rlarocque 2014/01/10 00:42:00 Hmm... These tests will be slow. We went out of o
haitaol1 2014/01/10 22:10:34 Done.
1310
1311 EXPECT_CALL(*syncer(), RetrySyncShare(_,_))
1312 .WillOnce(
1313 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
1314 RecordSyncShare(&times)));
1315
1316 // Run to wait for retrying.
1317 RunLoop();
1318
1319 EXPECT_GE(times[0] - t1, base::TimeDelta::FromSeconds(1));
1320
1321 StopSyncScheduler();
1322 }
1323
1324 TEST_F(SyncSchedulerTest, FaileRetry) {
rlarocque 2014/01/10 00:42:00 typo: FailRetry?
haitaol1 2014/01/10 22:10:34 Done.
1325 UseMockDelayProvider();
1326 EXPECT_CALL(*delay(), GetDelay(_))
1327 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1)));
1328
1329 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
1330
1331 scheduler()->OnReceivedGuRetryDelaySeconds(1);
1332
1333 EXPECT_CALL(*syncer(), RetrySyncShare(_,_))
1334 .WillOnce(
1335 DoAll(Invoke(sessions::test_util::SimulatePollRetryFailed),
1336 QuitLoopNowAction()));
1337
1338 // Run to wait for retrying.
1339 RunLoop();
1340
1341 EXPECT_TRUE(scheduler()->IsBackingOff());
1342 EXPECT_CALL(*syncer(), RetrySyncShare(_,_))
1343 .WillOnce(
1344 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
1345 QuitLoopNowAction()));
1346
1347 // Run to wait for second retrying.
1348 RunLoop();
1349
1350 StopSyncScheduler();
1351 }
1352
1353 TEST_F(SyncSchedulerTest, ReceiveNewRetryDelay) {
1354 StartSyncScheduler(SyncScheduler::NORMAL_MODE);
1355
1356 SyncShareTimes times;
1357 base::TimeTicks t1 = base::TimeTicks::Now();
1358 scheduler()->OnReceivedGuRetryDelaySeconds(1);
1359 scheduler()->ScheduleLocalRefreshRequest(zero(), ModelTypeSet(BOOKMARKS),
1360 FROM_HERE);
1361
1362 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
1363 .WillOnce(
1364 DoAll(WithArg<2>(sessions::test_util::SimulateGuRetryDelayCommand(2)),
1365 RecordSyncShare(&times)));
1366
1367 // Run nudge GU.
1368 RunLoop();
1369
1370 EXPECT_LT(times[0] - t1, base::TimeDelta::FromSeconds(1));
rlarocque 2014/01/10 00:42:00 This looks flaky. What if the timer takes an unus
haitaol1 2014/01/10 22:10:34 Done.
1371
1372 EXPECT_CALL(*syncer(), RetrySyncShare(_,_))
1373 .WillOnce(
1374 DoAll(Invoke(sessions::test_util::SimulatePollRetrySuccess),
1375 RecordSyncShare(&times)));
1376
1377 // Run to wait for retrying.
1378 RunLoop();
1379
1380 EXPECT_NEAR((times[1] - times[0]).InSeconds(), 2, 0.2);
rlarocque 2014/01/10 00:42:00 This one is almost certain to be flaky. We can't
haitaol1 2014/01/10 22:10:34 Done.
1381
1382 StopSyncScheduler();
1383 }
1384
1299 } // namespace syncer 1385 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698