| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/callback.h" | 6 #include "base/callback.h" |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 EXPECT_EQ(GetUpdatesCallerInfo::PERIODIC, | 143 EXPECT_EQ(GetUpdatesCallerInfo::PERIODIC, |
| 144 records.snapshots[i].source().updates_source); | 144 records.snapshots[i].source().updates_source); |
| 145 } | 145 } |
| 146 } | 146 } |
| 147 | 147 |
| 148 void DoQuitLoopNow() { | 148 void DoQuitLoopNow() { |
| 149 QuitLoopNow(); | 149 QuitLoopNow(); |
| 150 } | 150 } |
| 151 | 151 |
| 152 void StartSyncScheduler(SyncScheduler::Mode mode) { | 152 void StartSyncScheduler(SyncScheduler::Mode mode) { |
| 153 scheduler()->Start( | 153 scheduler()->Start(mode, base::Closure()); |
| 154 mode, | |
| 155 base::Bind(&SyncSchedulerTest::DoQuitLoopNow, | |
| 156 weak_ptr_factory_.GetWeakPtr())); | |
| 157 } | 154 } |
| 158 | 155 |
| 159 // This stops the scheduler synchronously. | 156 // This stops the scheduler synchronously. |
| 160 void StopSyncScheduler() { | 157 void StopSyncScheduler() { |
| 161 scheduler()->RequestStop(base::Bind(&SyncSchedulerTest::DoQuitLoopNow, | 158 scheduler()->RequestStop(base::Bind(&SyncSchedulerTest::DoQuitLoopNow, |
| 162 weak_ptr_factory_.GetWeakPtr())); | 159 weak_ptr_factory_.GetWeakPtr())); |
| 163 RunLoop(); | 160 RunLoop(); |
| 164 } | 161 } |
| 165 | 162 |
| 166 bool RunAndGetBackoff() { | 163 bool RunAndGetBackoff() { |
| 167 ModelTypeSet nudge_types; | 164 ModelTypeSet nudge_types; |
| 168 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 165 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 169 RunLoop(); | |
| 170 | 166 |
| 171 scheduler()->ScheduleNudge( | 167 scheduler()->ScheduleNudgeAsync( |
| 172 zero(), NUDGE_SOURCE_LOCAL, nudge_types, FROM_HERE); | 168 zero(), NUDGE_SOURCE_LOCAL, nudge_types, FROM_HERE); |
| 173 RunLoop(); | 169 RunLoop(); |
| 174 | 170 |
| 175 return scheduler()->IsBackingOff(); | 171 return scheduler()->IsBackingOff(); |
| 176 } | 172 } |
| 177 | 173 |
| 178 void UseMockDelayProvider() { | 174 void UseMockDelayProvider() { |
| 179 delay_ = new MockDelayProvider(); | 175 delay_ = new MockDelayProvider(); |
| 180 scheduler_->delay_provider_.reset(delay_); | 176 scheduler_->delay_provider_.reset(delay_); |
| 181 } | 177 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 208 TestDirectorySetterUpper dir_maker_; | 204 TestDirectorySetterUpper dir_maker_; |
| 209 scoped_ptr<MockConnectionManager> connection_; | 205 scoped_ptr<MockConnectionManager> connection_; |
| 210 scoped_ptr<SyncSessionContext> context_; | 206 scoped_ptr<SyncSessionContext> context_; |
| 211 scoped_ptr<SyncScheduler> scheduler_; | 207 scoped_ptr<SyncScheduler> scheduler_; |
| 212 MockSyncer* syncer_; | 208 MockSyncer* syncer_; |
| 213 MockDelayProvider* delay_; | 209 MockDelayProvider* delay_; |
| 214 std::vector<scoped_refptr<FakeModelWorker> > workers_; | 210 std::vector<scoped_refptr<FakeModelWorker> > workers_; |
| 215 FakeExtensionsActivityMonitor extensions_activity_monitor_; | 211 FakeExtensionsActivityMonitor extensions_activity_monitor_; |
| 216 }; | 212 }; |
| 217 | 213 |
| 218 class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest { | |
| 219 void SetUp() { | |
| 220 SyncSchedulerTest::SetUp(); | |
| 221 UseMockDelayProvider(); | |
| 222 EXPECT_CALL(*delay(), GetDelay(_)) | |
| 223 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); | |
| 224 } | |
| 225 | |
| 226 void TearDown() { | |
| 227 StopSyncScheduler(); | |
| 228 SyncSchedulerTest::TearDown(); | |
| 229 } | |
| 230 }; | |
| 231 | |
| 232 void RecordSyncShareImpl(SyncSession* s, SyncShareRecords* record) { | 214 void RecordSyncShareImpl(SyncSession* s, SyncShareRecords* record) { |
| 233 record->times.push_back(TimeTicks::Now()); | 215 record->times.push_back(TimeTicks::Now()); |
| 234 record->snapshots.push_back(s->TakeSnapshot()); | 216 record->snapshots.push_back(s->TakeSnapshot()); |
| 235 } | 217 } |
| 236 | 218 |
| 237 ACTION_P(RecordSyncShare, record) { | 219 ACTION_P(RecordSyncShare, record) { |
| 238 RecordSyncShareImpl(arg0, record); | 220 RecordSyncShareImpl(arg0, record); |
| 239 QuitLoopNow(); | 221 if (MessageLoop::current()->is_running()) |
| 222 QuitLoopNow(); |
| 240 } | 223 } |
| 241 | 224 |
| 242 ACTION_P2(RecordSyncShareMultiple, record, quit_after) { | 225 ACTION_P2(RecordSyncShareMultiple, record, quit_after) { |
| 243 RecordSyncShareImpl(arg0, record); | 226 RecordSyncShareImpl(arg0, record); |
| 244 EXPECT_LE(record->times.size(), quit_after); | 227 EXPECT_LE(record->times.size(), quit_after); |
| 245 if (record->times.size() >= quit_after) { | 228 if (record->times.size() >= quit_after && |
| 229 MessageLoop::current()->is_running()) { |
| 246 QuitLoopNow(); | 230 QuitLoopNow(); |
| 247 } | 231 } |
| 248 } | 232 } |
| 249 | 233 |
| 250 ACTION(AddFailureAndQuitLoopNow) { | 234 ACTION(AddFailureAndQuitLoopNow) { |
| 251 ADD_FAILURE(); | 235 ADD_FAILURE(); |
| 252 QuitLoopNow(); | 236 QuitLoopNow(); |
| 253 } | 237 } |
| 254 | 238 |
| 255 ACTION(QuitLoopNowAction) { | 239 ACTION(QuitLoopNowAction) { |
| 256 QuitLoopNow(); | 240 QuitLoopNow(); |
| 257 } | 241 } |
| 258 | 242 |
| 259 // Test nudge scheduling. | 243 // Test nudge scheduling. |
| 260 TEST_F(SyncSchedulerTest, Nudge) { | 244 TEST_F(SyncSchedulerTest, Nudge) { |
| 261 SyncShareRecords records; | 245 SyncShareRecords records; |
| 262 ModelTypeSet model_types(syncable::BOOKMARKS); | 246 ModelTypeSet model_types(syncable::BOOKMARKS); |
| 263 | 247 |
| 264 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 248 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 265 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 249 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 266 WithArg<0>(RecordSyncShare(&records)))) | 250 WithArg<0>(RecordSyncShare(&records)))) |
| 267 .RetiresOnSaturation(); | 251 .RetiresOnSaturation(); |
| 268 | 252 |
| 269 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 253 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 270 RunLoop(); | |
| 271 | 254 |
| 272 scheduler()->ScheduleNudge( | 255 scheduler()->ScheduleNudgeAsync( |
| 273 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); | 256 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); |
| 274 RunLoop(); | 257 RunLoop(); |
| 275 | 258 |
| 276 ASSERT_EQ(1U, records.snapshots.size()); | 259 ASSERT_EQ(1U, records.snapshots.size()); |
| 277 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, | 260 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, |
| 278 records.snapshots[0].source().types)); | 261 records.snapshots[0].source().types)); |
| 279 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 262 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 280 records.snapshots[0].source().updates_source); | 263 records.snapshots[0].source().updates_source); |
| 281 | 264 |
| 282 Mock::VerifyAndClearExpectations(syncer()); | 265 Mock::VerifyAndClearExpectations(syncer()); |
| 283 | 266 |
| 284 // Make sure a second, later, nudge is unaffected by first (no coalescing). | 267 // Make sure a second, later, nudge is unaffected by first (no coalescing). |
| 285 SyncShareRecords records2; | 268 SyncShareRecords records2; |
| 286 model_types.Remove(syncable::BOOKMARKS); | 269 model_types.Remove(syncable::BOOKMARKS); |
| 287 model_types.Put(syncable::AUTOFILL); | 270 model_types.Put(syncable::AUTOFILL); |
| 288 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 271 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 289 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 272 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 290 WithArg<0>(RecordSyncShare(&records2)))); | 273 WithArg<0>(RecordSyncShare(&records2)))); |
| 291 scheduler()->ScheduleNudge( | 274 scheduler()->ScheduleNudgeAsync( |
| 292 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); | 275 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); |
| 293 RunLoop(); | 276 RunLoop(); |
| 294 | 277 |
| 295 ASSERT_EQ(1U, records2.snapshots.size()); | 278 ASSERT_EQ(1U, records2.snapshots.size()); |
| 296 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, | 279 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, |
| 297 records2.snapshots[0].source().types)); | 280 records2.snapshots[0].source().types)); |
| 298 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 281 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 299 records2.snapshots[0].source().updates_source); | 282 records2.snapshots[0].source().updates_source); |
| 300 } | 283 } |
| 301 | 284 |
| 302 // Make sure a regular config command is scheduled fine in the absence of any | 285 // Make sure a regular config command is scheduled fine in the absence of any |
| 303 // errors. | 286 // errors. |
| 304 TEST_F(SyncSchedulerTest, Config) { | 287 TEST_F(SyncSchedulerTest, Config) { |
| 305 SyncShareRecords records; | 288 SyncShareRecords records; |
| 306 const ModelTypeSet model_types(syncable::BOOKMARKS); | 289 const ModelTypeSet model_types(syncable::BOOKMARKS); |
| 307 | 290 |
| 308 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 291 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 309 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 292 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 310 WithArg<0>(RecordSyncShare(&records)))); | 293 WithArg<0>(RecordSyncShare(&records)))); |
| 311 | 294 |
| 312 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 295 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 313 RunLoop(); | |
| 314 | 296 |
| 315 scheduler()->ScheduleConfig( | 297 scheduler()->ScheduleConfigure( |
| 316 model_types, GetUpdatesCallerInfo::RECONFIGURATION); | 298 model_types, GetUpdatesCallerInfo::RECONFIGURATION); |
| 317 RunLoop(); | |
| 318 | 299 |
| 319 ASSERT_EQ(1U, records.snapshots.size()); | 300 ASSERT_EQ(1U, records.snapshots.size()); |
| 320 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, | 301 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, |
| 321 records.snapshots[0].source().types)); | 302 records.snapshots[0].source().types)); |
| 322 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | 303 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, |
| 323 records.snapshots[0].source().updates_source); | 304 records.snapshots[0].source().updates_source); |
| 324 } | 305 } |
| 325 | 306 |
| 326 // Simulate a failure and make sure the config request is retried. | 307 // Simulate a failure and make sure the config request is retried. |
| 327 TEST_F(SyncSchedulerTest, ConfigWithBackingOff) { | 308 TEST_F(SyncSchedulerTest, ConfigWithBackingOff) { |
| 328 UseMockDelayProvider(); | 309 UseMockDelayProvider(); |
| 329 EXPECT_CALL(*delay(), GetDelay(_)) | 310 EXPECT_CALL(*delay(), GetDelay(_)) |
| 330 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); | 311 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); |
| 331 SyncShareRecords records; | 312 SyncShareRecords records; |
| 332 const ModelTypeSet model_types(syncable::BOOKMARKS); | 313 const ModelTypeSet model_types(syncable::BOOKMARKS); |
| 333 | 314 |
| 334 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 315 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 335 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 316 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 336 WithArg<0>(RecordSyncShare(&records)))) | 317 WithArg<0>(RecordSyncShare(&records)))) |
| 337 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 318 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 338 WithArg<0>(RecordSyncShare(&records)))); | 319 WithArg<0>(RecordSyncShare(&records)))); |
| 339 | 320 |
| 340 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 321 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 341 RunLoop(); | |
| 342 | 322 |
| 343 ASSERT_EQ(0U, records.snapshots.size()); | 323 ASSERT_EQ(0U, records.snapshots.size()); |
| 344 scheduler()->ScheduleConfig( | 324 scheduler()->ScheduleConfigure( |
| 345 model_types, GetUpdatesCallerInfo::RECONFIGURATION); | 325 model_types, GetUpdatesCallerInfo::RECONFIGURATION); |
| 346 RunLoop(); | |
| 347 | 326 |
| 348 ASSERT_EQ(1U, records.snapshots.size()); | 327 ASSERT_EQ(1U, records.snapshots.size()); |
| 349 RunLoop(); | 328 RunLoop(); |
| 350 | 329 |
| 351 ASSERT_EQ(2U, records.snapshots.size()); | 330 ASSERT_EQ(2U, records.snapshots.size()); |
| 352 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, | 331 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, |
| 353 records.snapshots[1].source().types)); | 332 records.snapshots[1].source().types)); |
| 354 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | 333 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, |
| 355 records.snapshots[1].source().updates_source); | 334 records.snapshots[1].source().updates_source); |
| 356 } | 335 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 368 | 347 |
| 369 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 348 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 370 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 349 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 371 WithArg<0>(RecordSyncShare(&records)))) | 350 WithArg<0>(RecordSyncShare(&records)))) |
| 372 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 351 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 373 WithArg<0>(RecordSyncShare(&records)))) | 352 WithArg<0>(RecordSyncShare(&records)))) |
| 374 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 353 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 375 WithArg<0>(RecordSyncShare(&records)))); | 354 WithArg<0>(RecordSyncShare(&records)))); |
| 376 | 355 |
| 377 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 356 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 378 RunLoop(); | |
| 379 | 357 |
| 380 ASSERT_EQ(0U, records.snapshots.size()); | 358 ASSERT_EQ(0U, records.snapshots.size()); |
| 381 scheduler()->ScheduleConfig( | 359 scheduler()->ScheduleConfigure( |
| 382 model_types1, GetUpdatesCallerInfo::RECONFIGURATION); | 360 model_types1, GetUpdatesCallerInfo::RECONFIGURATION); |
| 383 RunLoop(); | |
| 384 | 361 |
| 385 ASSERT_EQ(1U, records.snapshots.size()); | 362 ASSERT_EQ(1U, records.snapshots.size()); |
| 386 scheduler()->ScheduleConfig( | 363 scheduler()->ScheduleConfigure( |
| 387 model_types2, GetUpdatesCallerInfo::RECONFIGURATION); | 364 model_types2, GetUpdatesCallerInfo::RECONFIGURATION); |
| 365 |
| 366 // A canary job gets posted when we go into exponential backoff. |
| 388 RunLoop(); | 367 RunLoop(); |
| 389 | 368 |
| 390 ASSERT_EQ(2U, records.snapshots.size()); | 369 ASSERT_EQ(2U, records.snapshots.size()); |
| 391 RunLoop(); | 370 RunLoop(); |
| 392 | 371 |
| 393 ASSERT_EQ(3U, records.snapshots.size()); | 372 ASSERT_EQ(3U, records.snapshots.size()); |
| 394 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types2, | 373 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types2, |
| 395 records.snapshots[2].source().types)); | 374 records.snapshots[2].source().types)); |
| 396 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | 375 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, |
| 397 records.snapshots[2].source().updates_source); | 376 records.snapshots[2].source().updates_source); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 410 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 389 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 411 WithArg<0>(RecordSyncShare(&records)))) | 390 WithArg<0>(RecordSyncShare(&records)))) |
| 412 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 391 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 413 WithArg<0>(RecordSyncShare(&records)))) | 392 WithArg<0>(RecordSyncShare(&records)))) |
| 414 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 393 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 415 WithArg<0>(RecordSyncShare(&records)))) | 394 WithArg<0>(RecordSyncShare(&records)))) |
| 416 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 395 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 417 WithArg<0>(RecordSyncShare(&records)))); | 396 WithArg<0>(RecordSyncShare(&records)))); |
| 418 | 397 |
| 419 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 398 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 420 RunLoop(); | |
| 421 | 399 |
| 422 ASSERT_EQ(0U, records.snapshots.size()); | 400 ASSERT_EQ(0U, records.snapshots.size()); |
| 423 scheduler()->ScheduleConfig( | 401 scheduler()->ScheduleConfigure( |
| 424 model_types, GetUpdatesCallerInfo::RECONFIGURATION); | 402 model_types, GetUpdatesCallerInfo::RECONFIGURATION); |
| 425 RunLoop(); | |
| 426 | 403 |
| 427 ASSERT_EQ(1U, records.snapshots.size()); | 404 ASSERT_EQ(1U, records.snapshots.size()); |
| 428 scheduler()->ScheduleNudge( | 405 scheduler()->ScheduleNudgeAsync( |
| 429 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); | 406 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); |
| 430 RunLoop(); | 407 RunLoop(); |
| 431 | 408 |
| 432 ASSERT_EQ(2U, records.snapshots.size()); | 409 ASSERT_EQ(2U, records.snapshots.size()); |
| 433 RunLoop(); | 410 RunLoop(); |
| 434 | 411 |
| 435 // Now change the mode so nudge can execute. | 412 // Now change the mode so nudge can execute. |
| 436 ASSERT_EQ(3U, records.snapshots.size()); | 413 ASSERT_EQ(3U, records.snapshots.size()); |
| 437 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 414 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 438 RunLoop(); | |
| 439 | 415 |
| 440 ASSERT_EQ(4U, records.snapshots.size()); | 416 ASSERT_EQ(4U, records.snapshots.size()); |
| 441 | 417 |
| 442 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, | 418 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, |
| 443 records.snapshots[2].source().types)); | 419 records.snapshots[2].source().types)); |
| 444 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | 420 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, |
| 445 records.snapshots[2].source().updates_source); | 421 records.snapshots[2].source().updates_source); |
| 446 | 422 |
| 447 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, | 423 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(model_types, |
| 448 records.snapshots[3].source().types)); | 424 records.snapshots[3].source().types)); |
| 449 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 425 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 450 records.snapshots[3].source().updates_source); | 426 records.snapshots[3].source().updates_source); |
| 451 | 427 |
| 452 } | 428 } |
| 453 | 429 |
| 454 // Test that nudges are coalesced. | 430 // Test that nudges are coalesced. |
| 455 TEST_F(SyncSchedulerTest, NudgeCoalescing) { | 431 TEST_F(SyncSchedulerTest, NudgeCoalescing) { |
| 456 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 432 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 457 RunLoop(); | |
| 458 | 433 |
| 459 SyncShareRecords r; | 434 SyncShareRecords r; |
| 460 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 435 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 461 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 436 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 462 WithArg<0>(RecordSyncShare(&r)))); | 437 WithArg<0>(RecordSyncShare(&r)))); |
| 463 const ModelTypeSet | 438 const ModelTypeSet |
| 464 types1(syncable::BOOKMARKS), | 439 types1(syncable::BOOKMARKS), |
| 465 types2(syncable::AUTOFILL), | 440 types2(syncable::AUTOFILL), |
| 466 types3(syncable::THEMES); | 441 types3(syncable::THEMES); |
| 467 TimeDelta delay = zero(); | 442 TimeDelta delay = zero(); |
| 468 TimeTicks optimal_time = TimeTicks::Now() + delay; | 443 TimeTicks optimal_time = TimeTicks::Now() + delay; |
| 469 scheduler()->ScheduleNudge( | 444 scheduler()->ScheduleNudgeAsync( |
| 470 delay, NUDGE_SOURCE_UNKNOWN, types1, FROM_HERE); | 445 delay, NUDGE_SOURCE_UNKNOWN, types1, FROM_HERE); |
| 471 scheduler()->ScheduleNudge( | 446 scheduler()->ScheduleNudgeAsync( |
| 472 zero(), NUDGE_SOURCE_LOCAL, types2, FROM_HERE); | 447 zero(), NUDGE_SOURCE_LOCAL, types2, FROM_HERE); |
| 473 RunLoop(); | 448 RunLoop(); |
| 474 | 449 |
| 475 ASSERT_EQ(1U, r.snapshots.size()); | 450 ASSERT_EQ(1U, r.snapshots.size()); |
| 476 EXPECT_GE(r.times[0], optimal_time); | 451 EXPECT_GE(r.times[0], optimal_time); |
| 477 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap( | 452 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap( |
| 478 Union(types1, types2), r.snapshots[0].source().types)); | 453 Union(types1, types2), r.snapshots[0].source().types)); |
| 479 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 454 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 480 r.snapshots[0].source().updates_source); | 455 r.snapshots[0].source().updates_source); |
| 481 | 456 |
| 482 Mock::VerifyAndClearExpectations(syncer()); | 457 Mock::VerifyAndClearExpectations(syncer()); |
| 483 | 458 |
| 484 SyncShareRecords r2; | 459 SyncShareRecords r2; |
| 485 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 460 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 486 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 461 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 487 WithArg<0>(RecordSyncShare(&r2)))); | 462 WithArg<0>(RecordSyncShare(&r2)))); |
| 488 scheduler()->ScheduleNudge( | 463 scheduler()->ScheduleNudgeAsync( |
| 489 zero(), NUDGE_SOURCE_NOTIFICATION, types3, FROM_HERE); | 464 zero(), NUDGE_SOURCE_NOTIFICATION, types3, FROM_HERE); |
| 490 RunLoop(); | 465 RunLoop(); |
| 491 | 466 |
| 492 ASSERT_EQ(1U, r2.snapshots.size()); | 467 ASSERT_EQ(1U, r2.snapshots.size()); |
| 493 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(types3, | 468 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(types3, |
| 494 r2.snapshots[0].source().types)); | 469 r2.snapshots[0].source().types)); |
| 495 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, | 470 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, |
| 496 r2.snapshots[0].source().updates_source); | 471 r2.snapshots[0].source().updates_source); |
| 497 } | 472 } |
| 498 | 473 |
| 499 // Test that nudges are coalesced. | 474 // Test that nudges are coalesced. |
| 500 TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) { | 475 TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) { |
| 501 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 476 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 502 RunLoop(); | |
| 503 | 477 |
| 504 SyncShareRecords r; | 478 SyncShareRecords r; |
| 505 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 479 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 506 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 480 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 507 WithArg<0>(RecordSyncShare(&r)))); | 481 WithArg<0>(RecordSyncShare(&r)))); |
| 508 syncable::ModelTypeSet types1(syncable::BOOKMARKS), | 482 syncable::ModelTypeSet types1(syncable::BOOKMARKS), |
| 509 types2(syncable::AUTOFILL), types3; | 483 types2(syncable::AUTOFILL), types3; |
| 510 | 484 |
| 511 // Create a huge time delay. | 485 // Create a huge time delay. |
| 512 TimeDelta delay = TimeDelta::FromDays(1); | 486 TimeDelta delay = TimeDelta::FromDays(1); |
| 513 | 487 |
| 514 scheduler()->ScheduleNudge( | 488 scheduler()->ScheduleNudgeAsync( |
| 515 delay, NUDGE_SOURCE_UNKNOWN, types1, FROM_HERE); | 489 delay, NUDGE_SOURCE_UNKNOWN, types1, FROM_HERE); |
| 516 | 490 |
| 517 scheduler()->ScheduleNudge( | 491 scheduler()->ScheduleNudgeAsync( |
| 518 zero(), NUDGE_SOURCE_UNKNOWN, types2, FROM_HERE); | 492 zero(), NUDGE_SOURCE_UNKNOWN, types2, FROM_HERE); |
| 519 | 493 |
| 520 TimeTicks min_time = TimeTicks::Now(); | 494 TimeTicks min_time = TimeTicks::Now(); |
| 521 TimeTicks max_time = TimeTicks::Now() + delay; | 495 TimeTicks max_time = TimeTicks::Now() + delay; |
| 522 | 496 |
| 523 RunLoop(); | 497 RunLoop(); |
| 524 | 498 |
| 525 // Make sure the sync has happened. | 499 // Make sure the sync has happened. |
| 526 ASSERT_EQ(1U, r.snapshots.size()); | 500 ASSERT_EQ(1U, r.snapshots.size()); |
| 527 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap( | 501 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap( |
| 528 Union(types1, types2), r.snapshots[0].source().types)); | 502 Union(types1, types2), r.snapshots[0].source().types)); |
| 529 | 503 |
| 530 // Make sure the sync happened at the right time. | 504 // Make sure the sync happened at the right time. |
| 531 EXPECT_GE(r.times[0], min_time); | 505 EXPECT_GE(r.times[0], min_time); |
| 532 EXPECT_LE(r.times[0], max_time); | 506 EXPECT_LE(r.times[0], max_time); |
| 533 } | 507 } |
| 534 | 508 |
| 535 // Test nudge scheduling. | 509 // Test nudge scheduling. |
| 536 TEST_F(SyncSchedulerTest, NudgeWithPayloads) { | 510 TEST_F(SyncSchedulerTest, NudgeWithPayloads) { |
| 537 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 511 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 538 RunLoop(); | |
| 539 | 512 |
| 540 SyncShareRecords records; | 513 SyncShareRecords records; |
| 541 syncable::ModelTypePayloadMap model_types_with_payloads; | 514 syncable::ModelTypePayloadMap model_types_with_payloads; |
| 542 model_types_with_payloads[syncable::BOOKMARKS] = "test"; | 515 model_types_with_payloads[syncable::BOOKMARKS] = "test"; |
| 543 | 516 |
| 544 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 517 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 545 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 518 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 546 WithArg<0>(RecordSyncShare(&records)))) | 519 WithArg<0>(RecordSyncShare(&records)))) |
| 547 .RetiresOnSaturation(); | 520 .RetiresOnSaturation(); |
| 548 scheduler()->ScheduleNudgeWithPayloads( | 521 scheduler()->ScheduleNudgeWithPayloadsAsync( |
| 549 zero(), NUDGE_SOURCE_LOCAL, model_types_with_payloads, FROM_HERE); | 522 zero(), NUDGE_SOURCE_LOCAL, model_types_with_payloads, FROM_HERE); |
| 550 RunLoop(); | 523 RunLoop(); |
| 551 | 524 |
| 552 ASSERT_EQ(1U, records.snapshots.size()); | 525 ASSERT_EQ(1U, records.snapshots.size()); |
| 553 EXPECT_EQ(model_types_with_payloads, records.snapshots[0].source().types); | 526 EXPECT_EQ(model_types_with_payloads, records.snapshots[0].source().types); |
| 554 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 527 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 555 records.snapshots[0].source().updates_source); | 528 records.snapshots[0].source().updates_source); |
| 556 | 529 |
| 557 Mock::VerifyAndClearExpectations(syncer()); | 530 Mock::VerifyAndClearExpectations(syncer()); |
| 558 | 531 |
| 559 // Make sure a second, later, nudge is unaffected by first (no coalescing). | 532 // Make sure a second, later, nudge is unaffected by first (no coalescing). |
| 560 SyncShareRecords records2; | 533 SyncShareRecords records2; |
| 561 model_types_with_payloads.erase(syncable::BOOKMARKS); | 534 model_types_with_payloads.erase(syncable::BOOKMARKS); |
| 562 model_types_with_payloads[syncable::AUTOFILL] = "test2"; | 535 model_types_with_payloads[syncable::AUTOFILL] = "test2"; |
| 563 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 536 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 564 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 537 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 565 WithArg<0>(RecordSyncShare(&records2)))); | 538 WithArg<0>(RecordSyncShare(&records2)))); |
| 566 scheduler()->ScheduleNudgeWithPayloads( | 539 scheduler()->ScheduleNudgeWithPayloadsAsync( |
| 567 zero(), NUDGE_SOURCE_LOCAL, model_types_with_payloads, FROM_HERE); | 540 zero(), NUDGE_SOURCE_LOCAL, model_types_with_payloads, FROM_HERE); |
| 568 RunLoop(); | 541 RunLoop(); |
| 569 | 542 |
| 570 ASSERT_EQ(1U, records2.snapshots.size()); | 543 ASSERT_EQ(1U, records2.snapshots.size()); |
| 571 EXPECT_EQ(model_types_with_payloads, records2.snapshots[0].source().types); | 544 EXPECT_EQ(model_types_with_payloads, records2.snapshots[0].source().types); |
| 572 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 545 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 573 records2.snapshots[0].source().updates_source); | 546 records2.snapshots[0].source().updates_source); |
| 574 } | 547 } |
| 575 | 548 |
| 576 // Test that nudges are coalesced. | 549 // Test that nudges are coalesced. |
| 577 TEST_F(SyncSchedulerTest, NudgeWithPayloadsCoalescing) { | 550 TEST_F(SyncSchedulerTest, NudgeWithPayloadsCoalescing) { |
| 578 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 551 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 579 RunLoop(); | |
| 580 | 552 |
| 581 SyncShareRecords r; | 553 SyncShareRecords r; |
| 582 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 554 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 583 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 555 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 584 WithArg<0>(RecordSyncShare(&r)))); | 556 WithArg<0>(RecordSyncShare(&r)))); |
| 585 syncable::ModelTypePayloadMap types1, types2, types3; | 557 syncable::ModelTypePayloadMap types1, types2, types3; |
| 586 types1[syncable::BOOKMARKS] = "test1"; | 558 types1[syncable::BOOKMARKS] = "test1"; |
| 587 types2[syncable::AUTOFILL] = "test2"; | 559 types2[syncable::AUTOFILL] = "test2"; |
| 588 types3[syncable::THEMES] = "test3"; | 560 types3[syncable::THEMES] = "test3"; |
| 589 TimeDelta delay = zero(); | 561 TimeDelta delay = zero(); |
| 590 TimeTicks optimal_time = TimeTicks::Now() + delay; | 562 TimeTicks optimal_time = TimeTicks::Now() + delay; |
| 591 scheduler()->ScheduleNudgeWithPayloads( | 563 scheduler()->ScheduleNudgeWithPayloadsAsync( |
| 592 delay, NUDGE_SOURCE_UNKNOWN, types1, FROM_HERE); | 564 delay, NUDGE_SOURCE_UNKNOWN, types1, FROM_HERE); |
| 593 scheduler()->ScheduleNudgeWithPayloads( | 565 scheduler()->ScheduleNudgeWithPayloadsAsync( |
| 594 zero(), NUDGE_SOURCE_LOCAL, types2, FROM_HERE); | 566 zero(), NUDGE_SOURCE_LOCAL, types2, FROM_HERE); |
| 595 RunLoop(); | 567 RunLoop(); |
| 596 | 568 |
| 597 ASSERT_EQ(1U, r.snapshots.size()); | 569 ASSERT_EQ(1U, r.snapshots.size()); |
| 598 EXPECT_GE(r.times[0], optimal_time); | 570 EXPECT_GE(r.times[0], optimal_time); |
| 599 syncable::ModelTypePayloadMap coalesced_types; | 571 syncable::ModelTypePayloadMap coalesced_types; |
| 600 syncable::CoalescePayloads(&coalesced_types, types1); | 572 syncable::CoalescePayloads(&coalesced_types, types1); |
| 601 syncable::CoalescePayloads(&coalesced_types, types2); | 573 syncable::CoalescePayloads(&coalesced_types, types2); |
| 602 EXPECT_EQ(coalesced_types, r.snapshots[0].source().types); | 574 EXPECT_EQ(coalesced_types, r.snapshots[0].source().types); |
| 603 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 575 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 604 r.snapshots[0].source().updates_source); | 576 r.snapshots[0].source().updates_source); |
| 605 | 577 |
| 606 Mock::VerifyAndClearExpectations(syncer()); | 578 Mock::VerifyAndClearExpectations(syncer()); |
| 607 | 579 |
| 608 SyncShareRecords r2; | 580 SyncShareRecords r2; |
| 609 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 581 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 610 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 582 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 611 WithArg<0>(RecordSyncShare(&r2)))); | 583 WithArg<0>(RecordSyncShare(&r2)))); |
| 612 scheduler()->ScheduleNudgeWithPayloads( | 584 scheduler()->ScheduleNudgeWithPayloadsAsync( |
| 613 zero(), NUDGE_SOURCE_NOTIFICATION, types3, FROM_HERE); | 585 zero(), NUDGE_SOURCE_NOTIFICATION, types3, FROM_HERE); |
| 614 RunLoop(); | 586 RunLoop(); |
| 615 | 587 |
| 616 ASSERT_EQ(1U, r2.snapshots.size()); | 588 ASSERT_EQ(1U, r2.snapshots.size()); |
| 617 EXPECT_EQ(types3, r2.snapshots[0].source().types); | 589 EXPECT_EQ(types3, r2.snapshots[0].source().types); |
| 618 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, | 590 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, |
| 619 r2.snapshots[0].source().updates_source); | 591 r2.snapshots[0].source().updates_source); |
| 620 } | 592 } |
| 621 | 593 |
| 622 // Test that polling works as expected. | 594 // Test that polling works as expected. |
| 623 TEST_F(SyncSchedulerTest, Polling) { | 595 TEST_F(SyncSchedulerTest, Polling) { |
| 624 SyncShareRecords records; | 596 SyncShareRecords records; |
| 625 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); | 597 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); |
| 626 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples)) | 598 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples)) |
| 627 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 599 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 628 WithArg<0>(RecordSyncShareMultiple(&records, kMinNumSamples)))); | 600 WithArg<0>(RecordSyncShareMultiple(&records, kMinNumSamples)))); |
| 629 | 601 |
| 630 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | 602 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); |
| 631 | 603 |
| 632 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; | 604 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; |
| 633 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 605 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 634 RunLoop(); | |
| 635 | 606 |
| 636 // Run again to wait for polling. | 607 // Run again to wait for polling. |
| 637 RunLoop(); | 608 RunLoop(); |
| 638 | 609 |
| 639 StopSyncScheduler(); | 610 StopSyncScheduler(); |
| 640 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval); | 611 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval); |
| 641 } | 612 } |
| 642 | 613 |
| 643 // Test that the short poll interval is used. | 614 // Test that the short poll interval is used. |
| 644 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) { | 615 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) { |
| 645 SyncShareRecords records; | 616 SyncShareRecords records; |
| 646 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); | 617 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); |
| 647 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples)) | 618 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples)) |
| 648 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 619 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 649 WithArg<0>(RecordSyncShareMultiple(&records, kMinNumSamples)))); | 620 WithArg<0>(RecordSyncShareMultiple(&records, kMinNumSamples)))); |
| 650 | 621 |
| 651 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval); | 622 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval); |
| 652 scheduler()->set_notifications_enabled(false); | 623 scheduler()->set_notifications_enabled(false); |
| 653 | 624 |
| 654 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; | 625 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; |
| 655 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 626 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 656 RunLoop(); | |
| 657 | 627 |
| 658 // Run again to wait for polling. | 628 // Run again to wait for polling. |
| 659 RunLoop(); | 629 RunLoop(); |
| 660 | 630 |
| 661 StopSyncScheduler(); | 631 StopSyncScheduler(); |
| 662 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval); | 632 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval); |
| 663 } | 633 } |
| 664 | 634 |
| 665 // Test that polling intervals are updated when needed. | 635 // Test that polling intervals are updated when needed. |
| 666 TEST_F(SyncSchedulerTest, PollIntervalUpdate) { | 636 TEST_F(SyncSchedulerTest, PollIntervalUpdate) { |
| 667 SyncShareRecords records; | 637 SyncShareRecords records; |
| 668 TimeDelta poll1(TimeDelta::FromMilliseconds(120)); | 638 TimeDelta poll1(TimeDelta::FromMilliseconds(120)); |
| 669 TimeDelta poll2(TimeDelta::FromMilliseconds(30)); | 639 TimeDelta poll2(TimeDelta::FromMilliseconds(30)); |
| 670 scheduler()->OnReceivedLongPollIntervalUpdate(poll1); | 640 scheduler()->OnReceivedLongPollIntervalUpdate(poll1); |
| 671 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples)) | 641 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples)) |
| 672 .WillOnce(WithArg<0>( | 642 .WillOnce(WithArg<0>( |
| 673 sessions::test_util::SimulatePollIntervalUpdate(poll2))) | 643 sessions::test_util::SimulatePollIntervalUpdate(poll2))) |
| 674 .WillRepeatedly( | 644 .WillRepeatedly( |
| 675 DoAll(Invoke(sessions::test_util::SimulateSuccess), | 645 DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 676 WithArg<0>( | 646 WithArg<0>( |
| 677 RecordSyncShareMultiple(&records, kMinNumSamples)))); | 647 RecordSyncShareMultiple(&records, kMinNumSamples)))); |
| 678 | 648 |
| 679 TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2; | 649 TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2; |
| 680 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 650 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 681 RunLoop(); | |
| 682 | 651 |
| 683 // Run again to wait for polling. | 652 // Run again to wait for polling. |
| 684 RunLoop(); | 653 RunLoop(); |
| 685 | 654 |
| 686 StopSyncScheduler(); | 655 StopSyncScheduler(); |
| 687 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll2); | 656 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll2); |
| 688 } | 657 } |
| 689 | 658 |
| 690 // Test that the sessions commit delay is updated when needed. | 659 // Test that the sessions commit delay is updated when needed. |
| 691 TEST_F(SyncSchedulerTest, SessionsCommitDelay) { | 660 TEST_F(SyncSchedulerTest, SessionsCommitDelay) { |
| 692 SyncShareRecords records; | 661 SyncShareRecords records; |
| 693 TimeDelta delay1(TimeDelta::FromMilliseconds(120)); | 662 TimeDelta delay1(TimeDelta::FromMilliseconds(120)); |
| 694 TimeDelta delay2(TimeDelta::FromMilliseconds(30)); | 663 TimeDelta delay2(TimeDelta::FromMilliseconds(30)); |
| 695 scheduler()->OnReceivedSessionsCommitDelay(delay1); | 664 scheduler()->OnReceivedSessionsCommitDelay(delay1); |
| 696 | 665 |
| 697 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 666 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 698 .WillOnce( | 667 .WillOnce( |
| 699 DoAll( | 668 DoAll( |
| 700 WithArg<0>( | 669 WithArg<0>( |
| 701 sessions::test_util::SimulateSessionsCommitDelayUpdate( | 670 sessions::test_util::SimulateSessionsCommitDelayUpdate( |
| 702 delay2)), | 671 delay2)), |
| 703 Invoke(sessions::test_util::SimulateSuccess), | 672 Invoke(sessions::test_util::SimulateSuccess), |
| 704 QuitLoopNowAction())); | 673 QuitLoopNowAction())); |
| 705 | 674 |
| 706 EXPECT_EQ(delay1, scheduler()->sessions_commit_delay()); | 675 EXPECT_EQ(delay1, scheduler()->sessions_commit_delay()); |
| 707 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 676 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 708 RunLoop(); | |
| 709 | 677 |
| 710 EXPECT_EQ(delay1, scheduler()->sessions_commit_delay()); | 678 EXPECT_EQ(delay1, scheduler()->sessions_commit_delay()); |
| 711 const ModelTypeSet model_types(syncable::BOOKMARKS); | 679 const ModelTypeSet model_types(syncable::BOOKMARKS); |
| 712 scheduler()->ScheduleNudge( | 680 scheduler()->ScheduleNudgeAsync( |
| 713 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); | 681 zero(), NUDGE_SOURCE_LOCAL, model_types, FROM_HERE); |
| 714 RunLoop(); | 682 RunLoop(); |
| 715 | 683 |
| 716 EXPECT_EQ(delay2, scheduler()->sessions_commit_delay()); | 684 EXPECT_EQ(delay2, scheduler()->sessions_commit_delay()); |
| 717 StopSyncScheduler(); | 685 StopSyncScheduler(); |
| 718 } | 686 } |
| 719 | 687 |
| 720 // Test that a sync session is run through to completion. | 688 // Test that a sync session is run through to completion. |
| 721 TEST_F(SyncSchedulerTest, HasMoreToSync) { | 689 TEST_F(SyncSchedulerTest, HasMoreToSync) { |
| 722 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 690 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 723 .WillOnce(Invoke(sessions::test_util::SimulateHasMoreToSync)) | 691 .WillOnce(Invoke(sessions::test_util::SimulateHasMoreToSync)) |
| 724 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 692 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 725 QuitLoopNowAction())); | 693 QuitLoopNowAction())); |
| 726 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 694 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 727 RunLoop(); | |
| 728 | 695 |
| 729 scheduler()->ScheduleNudge( | 696 scheduler()->ScheduleNudgeAsync( |
| 730 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); | 697 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); |
| 731 RunLoop(); | 698 RunLoop(); |
| 732 // If more nudges are scheduled, they'll be waited on by TearDown, and would | 699 // If more nudges are scheduled, they'll be waited on by TearDown, and would |
| 733 // cause our expectation to break. | 700 // cause our expectation to break. |
| 734 } | 701 } |
| 735 | 702 |
| 736 // Test that continuations can go into backoff. | 703 // Test that continuations can go into backoff. |
| 737 TEST_F(SyncSchedulerTest, HasMoreToSyncThenFails) { | 704 TEST_F(SyncSchedulerTest, HasMoreToSyncThenFails) { |
| 738 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 705 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 739 .WillOnce(Invoke(sessions::test_util::SimulateHasMoreToSync)) | 706 .WillOnce(Invoke(sessions::test_util::SimulateHasMoreToSync)) |
| 740 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 707 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 741 QuitLoopNowAction())); | 708 QuitLoopNowAction())); |
| 742 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 709 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 743 RunLoop(); | |
| 744 | 710 |
| 745 scheduler()->ScheduleNudge( | 711 scheduler()->ScheduleNudgeAsync( |
| 746 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); | 712 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); |
| 747 | 713 |
| 748 // We should detect the failure on the second sync share, and go into backoff. | 714 // We should detect the failure on the second sync share, and go into backoff. |
| 749 EXPECT_TRUE(RunAndGetBackoff()); | 715 EXPECT_TRUE(RunAndGetBackoff()); |
| 750 } | 716 } |
| 751 | 717 |
| 752 // Test that no syncing occurs when throttled. | 718 // Test that no syncing occurs when throttled. |
| 753 TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) { | 719 TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) { |
| 754 const ModelTypeSet types(syncable::BOOKMARKS); | 720 const ModelTypeSet types(syncable::BOOKMARKS); |
| 755 TimeDelta poll(TimeDelta::FromMilliseconds(5)); | 721 TimeDelta poll(TimeDelta::FromMilliseconds(5)); |
| 756 TimeDelta throttle(TimeDelta::FromMinutes(10)); | 722 TimeDelta throttle(TimeDelta::FromMinutes(10)); |
| 757 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 723 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 758 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 724 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 759 .WillOnce(WithArg<0>(sessions::test_util::SimulateThrottled(throttle))) | 725 .WillOnce(WithArg<0>(sessions::test_util::SimulateThrottled(throttle))) |
| 760 .WillRepeatedly(AddFailureAndQuitLoopNow()); | 726 .WillRepeatedly(AddFailureAndQuitLoopNow()); |
| 761 | 727 |
| 762 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 728 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 763 RunLoop(); | |
| 764 | 729 |
| 765 scheduler()->ScheduleNudge( | 730 scheduler()->ScheduleNudgeAsync( |
| 766 zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); | 731 zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); |
| 767 PumpLoop(); | 732 PumpLoop(); |
| 768 | 733 |
| 769 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 734 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 770 RunLoop(); | |
| 771 | 735 |
| 772 scheduler()->ScheduleConfig( | 736 scheduler()->ScheduleConfigure( |
| 773 types, GetUpdatesCallerInfo::RECONFIGURATION); | 737 types, GetUpdatesCallerInfo::RECONFIGURATION); |
| 774 PumpLoop(); | |
| 775 } | 738 } |
| 776 | 739 |
| 777 TEST_F(SyncSchedulerTest, ThrottlingExpires) { | 740 TEST_F(SyncSchedulerTest, ThrottlingExpires) { |
| 778 SyncShareRecords records; | 741 SyncShareRecords records; |
| 779 TimeDelta poll(TimeDelta::FromMilliseconds(15)); | 742 TimeDelta poll(TimeDelta::FromMilliseconds(15)); |
| 780 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); | 743 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); |
| 781 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 744 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 782 | 745 |
| 783 ::testing::InSequence seq; | 746 ::testing::InSequence seq; |
| 784 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 747 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 785 .WillOnce(WithArg<0>(sessions::test_util::SimulateThrottled(throttle1))) | 748 .WillOnce(WithArg<0>(sessions::test_util::SimulateThrottled(throttle1))) |
| 786 .RetiresOnSaturation(); | 749 .RetiresOnSaturation(); |
| 787 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 750 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 788 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 751 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 789 WithArg<0>(RecordSyncShareMultiple(&records, kMinNumSamples)))); | 752 WithArg<0>(RecordSyncShareMultiple(&records, kMinNumSamples)))); |
| 790 | 753 |
| 791 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1; | 754 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1; |
| 792 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 755 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 793 RunLoop(); | |
| 794 | 756 |
| 795 // Run again to wait for polling. | 757 // Run again to wait for polling. |
| 796 RunLoop(); | 758 RunLoop(); |
| 797 | 759 |
| 798 StopSyncScheduler(); | 760 StopSyncScheduler(); |
| 799 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll); | 761 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll); |
| 800 } | 762 } |
| 801 | 763 |
| 802 // Test nudges / polls don't run in config mode and config tasks do. | 764 // Test nudges / polls don't run in config mode and config tasks do. |
| 803 TEST_F(SyncSchedulerTest, ConfigurationMode) { | 765 TEST_F(SyncSchedulerTest, ConfigurationMode) { |
| 804 TimeDelta poll(TimeDelta::FromMilliseconds(15)); | 766 TimeDelta poll(TimeDelta::FromMilliseconds(15)); |
| 805 SyncShareRecords records; | 767 SyncShareRecords records; |
| 806 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 768 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 807 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 769 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 808 .WillOnce((Invoke(sessions::test_util::SimulateSuccess), | 770 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 809 WithArg<0>(RecordSyncShare(&records)))); | 771 WithArg<0>(RecordSyncShare(&records)))); |
| 810 | 772 |
| 811 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 773 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 812 RunLoop(); | |
| 813 | 774 |
| 814 const ModelTypeSet nudge_types(syncable::AUTOFILL); | 775 const ModelTypeSet nudge_types(syncable::AUTOFILL); |
| 815 scheduler()->ScheduleNudge( | 776 scheduler()->ScheduleNudgeAsync( |
| 816 zero(), NUDGE_SOURCE_LOCAL, nudge_types, FROM_HERE); | 777 zero(), NUDGE_SOURCE_LOCAL, nudge_types, FROM_HERE); |
| 817 scheduler()->ScheduleNudge( | 778 scheduler()->ScheduleNudgeAsync( |
| 818 zero(), NUDGE_SOURCE_LOCAL, nudge_types, FROM_HERE); | 779 zero(), NUDGE_SOURCE_LOCAL, nudge_types, FROM_HERE); |
| 819 | 780 |
| 820 const ModelTypeSet config_types(syncable::BOOKMARKS); | 781 const ModelTypeSet config_types(syncable::BOOKMARKS); |
| 821 | 782 |
| 822 scheduler()->ScheduleConfig( | 783 scheduler()->ScheduleConfigure( |
| 823 config_types, GetUpdatesCallerInfo::RECONFIGURATION); | 784 config_types, GetUpdatesCallerInfo::RECONFIGURATION); |
| 824 RunLoop(); | |
| 825 | 785 |
| 826 ASSERT_EQ(1U, records.snapshots.size()); | 786 ASSERT_EQ(1U, records.snapshots.size()); |
| 827 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(config_types, | 787 EXPECT_TRUE(CompareModelTypeSetToModelTypePayloadMap(config_types, |
| 828 records.snapshots[0].source().types)); | 788 records.snapshots[0].source().types)); |
| 829 } | 789 } |
| 830 | 790 |
| 791 class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest { |
| 792 void SetUp() { |
| 793 SyncSchedulerTest::SetUp(); |
| 794 UseMockDelayProvider(); |
| 795 EXPECT_CALL(*delay(), GetDelay(_)) |
| 796 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); |
| 797 } |
| 798 |
| 799 void TearDown() { |
| 800 StopSyncScheduler(); |
| 801 SyncSchedulerTest::TearDown(); |
| 802 } |
| 803 }; |
| 804 |
| 831 // Have the sycner fail during commit. Expect that the scheduler enters | 805 // Have the sycner fail during commit. Expect that the scheduler enters |
| 832 // backoff. | 806 // backoff. |
| 833 TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnce) { | 807 TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnce) { |
| 834 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 808 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 835 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 809 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 836 QuitLoopNowAction())); | 810 QuitLoopNowAction())); |
| 837 EXPECT_TRUE(RunAndGetBackoff()); | 811 EXPECT_TRUE(RunAndGetBackoff()); |
| 838 } | 812 } |
| 839 | 813 |
| 840 // Have the syncer fail during download updates and succeed on the first | 814 // Have the syncer fail during download updates and succeed on the first |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 850 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 877 UseMockDelayProvider(); | 851 UseMockDelayProvider(); |
| 878 | 852 |
| 879 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1) | 853 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1) |
| 880 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 854 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 881 RecordSyncShareMultiple(&r, 1U))); | 855 RecordSyncShareMultiple(&r, 1U))); |
| 882 EXPECT_CALL(*delay(), GetDelay(_)). | 856 EXPECT_CALL(*delay(), GetDelay(_)). |
| 883 WillRepeatedly(Return(TimeDelta::FromDays(1))); | 857 WillRepeatedly(Return(TimeDelta::FromDays(1))); |
| 884 | 858 |
| 885 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 859 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 886 RunLoop(); | |
| 887 | 860 |
| 888 // This nudge should fail and put us into backoff. Thanks to our mock | 861 // This nudge should fail and put us into backoff. Thanks to our mock |
| 889 // GetDelay() setup above, this will be a long backoff. | 862 // GetDelay() setup above, this will be a long backoff. |
| 890 scheduler()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); | 863 scheduler()->ScheduleNudgeAsync(zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); |
| 891 RunLoop(); | 864 RunLoop(); |
| 892 | 865 |
| 893 Mock::VerifyAndClearExpectations(syncer()); | 866 Mock::VerifyAndClearExpectations(syncer()); |
| 894 ASSERT_EQ(1U, r.snapshots.size()); | 867 ASSERT_EQ(1U, r.snapshots.size()); |
| 895 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 868 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 896 r.snapshots[0].source().updates_source); | 869 r.snapshots[0].source().updates_source); |
| 897 | 870 |
| 898 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1) | 871 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1) |
| 899 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 872 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 900 RecordSyncShare(&r))); | 873 RecordSyncShare(&r))); |
| 901 | 874 |
| 902 // We schedule a nudge with enough delay (10X poll interval) that at least | 875 // We schedule a nudge with enough delay (10X poll interval) that at least |
| 903 // one or two polls would have taken place. The nudge should succeed. | 876 // one or two polls would have taken place. The nudge should succeed. |
| 904 scheduler()->ScheduleNudge(poll * 10, NUDGE_SOURCE_LOCAL, types, FROM_HERE); | 877 scheduler()->ScheduleNudgeAsync( |
| 878 poll * 10, NUDGE_SOURCE_LOCAL, types, FROM_HERE); |
| 905 RunLoop(); | 879 RunLoop(); |
| 906 | 880 |
| 907 Mock::VerifyAndClearExpectations(syncer()); | 881 Mock::VerifyAndClearExpectations(syncer()); |
| 908 Mock::VerifyAndClearExpectations(delay()); | 882 Mock::VerifyAndClearExpectations(delay()); |
| 909 ASSERT_EQ(2U, r.snapshots.size()); | 883 ASSERT_EQ(2U, r.snapshots.size()); |
| 910 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 884 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| 911 r.snapshots[1].source().updates_source); | 885 r.snapshots[1].source().updates_source); |
| 912 | 886 |
| 913 // Cleanup is not affected by backoff, but it should not relieve it either. | 887 // Cleanup is not affected by backoff, but it should not relieve it either. |
| 914 EXPECT_CALL(*syncer(), | 888 EXPECT_CALL(*syncer(), |
| 915 SyncShare(_, CLEANUP_DISABLED_TYPES, CLEANUP_DISABLED_TYPES)) | 889 SyncShare(_, CLEANUP_DISABLED_TYPES, CLEANUP_DISABLED_TYPES)) |
| 916 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); | 890 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); |
| 917 EXPECT_CALL(*delay(), GetDelay(_)).Times(0); | 891 EXPECT_CALL(*delay(), GetDelay(_)).Times(0); |
| 918 | 892 |
| 919 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 893 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 920 RunLoop(); | |
| 921 | 894 |
| 922 scheduler()->ScheduleCleanupDisabledTypes(); | 895 scheduler()->CleanupDisabledTypes(); |
| 923 scheduler()->ScheduleConfig( | 896 scheduler()->ScheduleConfigure( |
| 924 types, GetUpdatesCallerInfo::RECONFIGURATION); | 897 types, GetUpdatesCallerInfo::RECONFIGURATION); |
| 925 PumpLoop(); | |
| 926 | 898 |
| 927 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 899 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 928 RunLoop(); | |
| 929 | 900 |
| 930 scheduler()->ScheduleNudge( | 901 scheduler()->ScheduleNudgeAsync( |
| 931 zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); | 902 zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); |
| 932 scheduler()->ScheduleNudge( | 903 scheduler()->ScheduleNudgeAsync( |
| 933 zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); | 904 zero(), NUDGE_SOURCE_LOCAL, types, FROM_HERE); |
| 934 PumpLoop(); | 905 PumpLoop(); |
| 935 } | 906 } |
| 936 | 907 |
| 937 // Test that backoff is shaping traffic properly with consecutive errors. | 908 // Test that backoff is shaping traffic properly with consecutive errors. |
| 938 TEST_F(SyncSchedulerTest, BackoffElevation) { | 909 TEST_F(SyncSchedulerTest, BackoffElevation) { |
| 939 SyncShareRecords r; | 910 SyncShareRecords r; |
| 940 UseMockDelayProvider(); | 911 UseMockDelayProvider(); |
| 941 | 912 |
| 942 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(kMinNumSamples) | 913 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(kMinNumSamples) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 954 .RetiresOnSaturation(); | 925 .RetiresOnSaturation(); |
| 955 EXPECT_CALL(*delay(), GetDelay(Eq(second))).WillOnce(Return(third)) | 926 EXPECT_CALL(*delay(), GetDelay(Eq(second))).WillOnce(Return(third)) |
| 956 .RetiresOnSaturation(); | 927 .RetiresOnSaturation(); |
| 957 EXPECT_CALL(*delay(), GetDelay(Eq(third))).WillOnce(Return(fourth)) | 928 EXPECT_CALL(*delay(), GetDelay(Eq(third))).WillOnce(Return(fourth)) |
| 958 .RetiresOnSaturation(); | 929 .RetiresOnSaturation(); |
| 959 EXPECT_CALL(*delay(), GetDelay(Eq(fourth))).WillOnce(Return(fifth)) | 930 EXPECT_CALL(*delay(), GetDelay(Eq(fourth))).WillOnce(Return(fifth)) |
| 960 .RetiresOnSaturation(); | 931 .RetiresOnSaturation(); |
| 961 EXPECT_CALL(*delay(), GetDelay(Eq(fifth))).WillOnce(Return(sixth)); | 932 EXPECT_CALL(*delay(), GetDelay(Eq(fifth))).WillOnce(Return(sixth)); |
| 962 | 933 |
| 963 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 934 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 964 RunLoop(); | |
| 965 | 935 |
| 966 // Run again with a nudge. | 936 // Run again with a nudge. |
| 967 scheduler()->ScheduleNudge( | 937 scheduler()->ScheduleNudgeAsync( |
| 968 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); | 938 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); |
| 969 RunLoop(); | 939 RunLoop(); |
| 970 | 940 |
| 971 ASSERT_EQ(kMinNumSamples, r.snapshots.size()); | 941 ASSERT_EQ(kMinNumSamples, r.snapshots.size()); |
| 972 EXPECT_GE(r.times[1] - r.times[0], second); | 942 EXPECT_GE(r.times[1] - r.times[0], second); |
| 973 EXPECT_GE(r.times[2] - r.times[1], third); | 943 EXPECT_GE(r.times[2] - r.times[1], third); |
| 974 EXPECT_GE(r.times[3] - r.times[2], fourth); | 944 EXPECT_GE(r.times[3] - r.times[2], fourth); |
| 975 EXPECT_GE(r.times[4] - r.times[3], fifth); | 945 EXPECT_GE(r.times[4] - r.times[3], fifth); |
| 976 } | 946 } |
| 977 | 947 |
| 978 // Test that things go back to normal once a retry makes forward progress. | 948 // Test that things go back to normal once a retry makes forward progress. |
| 979 TEST_F(SyncSchedulerTest, BackoffRelief) { | 949 TEST_F(SyncSchedulerTest, BackoffRelief) { |
| 980 SyncShareRecords r; | 950 SyncShareRecords r; |
| 981 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); | 951 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); |
| 982 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 952 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 983 UseMockDelayProvider(); | 953 UseMockDelayProvider(); |
| 984 | 954 |
| 985 const TimeDelta backoff = TimeDelta::FromMilliseconds(5); | 955 const TimeDelta backoff = TimeDelta::FromMilliseconds(5); |
| 986 | 956 |
| 987 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 957 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 988 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 958 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 989 RecordSyncShareMultiple(&r, kMinNumSamples))) | 959 RecordSyncShareMultiple(&r, kMinNumSamples))) |
| 990 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 960 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 991 RecordSyncShareMultiple(&r, kMinNumSamples))); | 961 RecordSyncShareMultiple(&r, kMinNumSamples))); |
| 992 EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff)); | 962 EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff)); |
| 993 | 963 |
| 994 // Optimal start for the post-backoff poll party. | 964 // Optimal start for the post-backoff poll party. |
| 995 TimeTicks optimal_start = TimeTicks::Now(); | 965 TimeTicks optimal_start = TimeTicks::Now(); |
| 996 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 966 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 997 RunLoop(); | |
| 998 | 967 |
| 999 // Run again to wait for polling. | 968 // Run again to wait for polling. |
| 1000 scheduler()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, | 969 scheduler()->ScheduleNudgeAsync(zero(), NUDGE_SOURCE_LOCAL, |
| 1001 ModelTypeSet(), FROM_HERE); | 970 ModelTypeSet(), FROM_HERE); |
| 1002 RunLoop(); | 971 RunLoop(); |
| 1003 | 972 |
| 1004 StopSyncScheduler(); | 973 StopSyncScheduler(); |
| 1005 | 974 |
| 1006 EXPECT_EQ(kMinNumSamples, r.times.size()); | 975 EXPECT_EQ(kMinNumSamples, r.times.size()); |
| 1007 | 976 |
| 1008 // The first nudge ran as soon as possible. It failed. | 977 // The first nudge ran as soon as possible. It failed. |
| 1009 TimeTicks optimal_job_time = optimal_start; | 978 TimeTicks optimal_job_time = optimal_start; |
| 1010 EXPECT_GE(r.times[0], optimal_job_time); | 979 EXPECT_GE(r.times[0], optimal_job_time); |
| 1011 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 980 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1034 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | 1003 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); |
| 1035 UseMockDelayProvider(); // Will cause test failure if backoff is initiated. | 1004 UseMockDelayProvider(); // Will cause test failure if backoff is initiated. |
| 1036 | 1005 |
| 1037 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 1006 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 1038 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 1007 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 1039 RecordSyncShare(&r))) | 1008 RecordSyncShare(&r))) |
| 1040 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 1009 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 1041 RecordSyncShare(&r))); | 1010 RecordSyncShare(&r))); |
| 1042 | 1011 |
| 1043 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1012 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1044 RunLoop(); | |
| 1045 | 1013 |
| 1046 // Run the unsucessful poll. The failed poll should not trigger backoff. | 1014 // Run the unsucessful poll. The failed poll should not trigger backoff. |
| 1047 RunLoop(); | 1015 RunLoop(); |
| 1048 EXPECT_FALSE(scheduler()->IsBackingOff()); | 1016 EXPECT_FALSE(scheduler()->IsBackingOff()); |
| 1049 | 1017 |
| 1050 // Run the successful poll. | 1018 // Run the successful poll. |
| 1051 RunLoop(); | 1019 RunLoop(); |
| 1052 EXPECT_FALSE(scheduler()->IsBackingOff()); | 1020 EXPECT_FALSE(scheduler()->IsBackingOff()); |
| 1053 } | 1021 } |
| 1054 | 1022 |
| 1055 TEST_F(SyncSchedulerTest, GetRecommendedDelay) { | 1023 TEST_F(SyncSchedulerTest, GetRecommendedDelay) { |
| 1056 EXPECT_LE(TimeDelta::FromSeconds(0), | 1024 EXPECT_LE(TimeDelta::FromSeconds(0), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1068 SyncScheduler::GetRecommendedDelay( | 1036 SyncScheduler::GetRecommendedDelay( |
| 1069 TimeDelta::FromSeconds(kMaxBackoffSeconds + 1))); | 1037 TimeDelta::FromSeconds(kMaxBackoffSeconds + 1))); |
| 1070 } | 1038 } |
| 1071 | 1039 |
| 1072 // Test that appropriate syncer steps are requested for each job type. | 1040 // Test that appropriate syncer steps are requested for each job type. |
| 1073 TEST_F(SyncSchedulerTest, SyncerSteps) { | 1041 TEST_F(SyncSchedulerTest, SyncerSteps) { |
| 1074 // Nudges. | 1042 // Nudges. |
| 1075 EXPECT_CALL(*syncer(), SyncShare(_, SYNCER_BEGIN, SYNCER_END)) | 1043 EXPECT_CALL(*syncer(), SyncShare(_, SYNCER_BEGIN, SYNCER_END)) |
| 1076 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); | 1044 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); |
| 1077 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1045 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1078 RunLoop(); | |
| 1079 | 1046 |
| 1080 scheduler()->ScheduleNudge( | 1047 scheduler()->ScheduleNudgeAsync( |
| 1081 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); | 1048 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); |
| 1082 PumpLoop(); | 1049 PumpLoop(); |
| 1083 // Pump again to run job. | 1050 // Pump again to run job. |
| 1084 PumpLoop(); | 1051 PumpLoop(); |
| 1085 | 1052 |
| 1086 StopSyncScheduler(); | 1053 StopSyncScheduler(); |
| 1087 Mock::VerifyAndClearExpectations(syncer()); | 1054 Mock::VerifyAndClearExpectations(syncer()); |
| 1088 | 1055 |
| 1089 // ClearUserData. | 1056 // ClearUserData. |
| 1090 EXPECT_CALL(*syncer(), SyncShare(_, CLEAR_PRIVATE_DATA, CLEAR_PRIVATE_DATA)) | 1057 EXPECT_CALL(*syncer(), SyncShare(_, CLEAR_PRIVATE_DATA, CLEAR_PRIVATE_DATA)) |
| 1091 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); | 1058 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); |
| 1092 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1059 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1093 RunLoop(); | |
| 1094 | 1060 |
| 1095 scheduler()->ScheduleClearUserData(); | 1061 scheduler()->ClearUserData(); |
| 1096 PumpLoop(); | |
| 1097 PumpLoop(); | |
| 1098 | 1062 |
| 1099 StopSyncScheduler(); | 1063 StopSyncScheduler(); |
| 1100 Mock::VerifyAndClearExpectations(syncer()); | 1064 Mock::VerifyAndClearExpectations(syncer()); |
| 1101 | 1065 |
| 1102 // Configuration. | 1066 // Configuration. |
| 1103 EXPECT_CALL(*syncer(), SyncShare(_, DOWNLOAD_UPDATES, APPLY_UPDATES)) | 1067 EXPECT_CALL(*syncer(), SyncShare(_, DOWNLOAD_UPDATES, APPLY_UPDATES)) |
| 1104 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); | 1068 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); |
| 1105 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 1069 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 1106 RunLoop(); | |
| 1107 | 1070 |
| 1108 scheduler()->ScheduleConfig( | 1071 scheduler()->ScheduleConfigure( |
| 1109 ModelTypeSet(), GetUpdatesCallerInfo::RECONFIGURATION); | 1072 ModelTypeSet(), GetUpdatesCallerInfo::RECONFIGURATION); |
| 1110 PumpLoop(); | |
| 1111 PumpLoop(); | |
| 1112 | 1073 |
| 1113 StopSyncScheduler(); | 1074 StopSyncScheduler(); |
| 1114 Mock::VerifyAndClearExpectations(syncer()); | 1075 Mock::VerifyAndClearExpectations(syncer()); |
| 1115 | 1076 |
| 1116 // Cleanup disabled types. | 1077 // Cleanup disabled types. |
| 1117 EXPECT_CALL(*syncer(), | 1078 EXPECT_CALL(*syncer(), |
| 1118 SyncShare(_, CLEANUP_DISABLED_TYPES, CLEANUP_DISABLED_TYPES)) | 1079 SyncShare(_, CLEANUP_DISABLED_TYPES, CLEANUP_DISABLED_TYPES)) |
| 1119 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); | 1080 .WillOnce(Invoke(sessions::test_util::SimulateSuccess)); |
| 1120 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1081 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1121 RunLoop(); | |
| 1122 | 1082 |
| 1123 scheduler()->ScheduleCleanupDisabledTypes(); | 1083 scheduler()->CleanupDisabledTypes(); |
| 1124 // Only need to pump once, as ScheduleCleanupDisabledTypes() | |
| 1125 // schedules the job directly. | |
| 1126 PumpLoop(); | |
| 1127 | 1084 |
| 1128 StopSyncScheduler(); | 1085 StopSyncScheduler(); |
| 1129 Mock::VerifyAndClearExpectations(syncer()); | 1086 Mock::VerifyAndClearExpectations(syncer()); |
| 1130 | 1087 |
| 1131 // Poll. | 1088 // Poll. |
| 1132 EXPECT_CALL(*syncer(), SyncShare(_, SYNCER_BEGIN, SYNCER_END)) | 1089 EXPECT_CALL(*syncer(), SyncShare(_, SYNCER_BEGIN, SYNCER_END)) |
| 1133 .Times(AtLeast(1)) | 1090 .Times(AtLeast(1)) |
| 1134 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 1091 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
| 1135 QuitLoopNowAction())); | 1092 QuitLoopNowAction())); |
| 1136 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); | 1093 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); |
| 1137 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 1094 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 1138 | 1095 |
| 1139 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1096 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1140 RunLoop(); | |
| 1141 | 1097 |
| 1142 // Run again to wait for polling. | 1098 // Run again to wait for polling. |
| 1143 RunLoop(); | 1099 RunLoop(); |
| 1144 | 1100 |
| 1145 StopSyncScheduler(); | 1101 StopSyncScheduler(); |
| 1146 Mock::VerifyAndClearExpectations(syncer()); | 1102 Mock::VerifyAndClearExpectations(syncer()); |
| 1147 } | 1103 } |
| 1148 | 1104 |
| 1149 // Test config tasks don't run during normal mode. | 1105 // Test config tasks don't run during normal mode. |
| 1150 // TODO(tim): Implement this test and then the functionality! | 1106 // TODO(tim): Implement this test and then the functionality! |
| 1151 TEST_F(SyncSchedulerTest, DISABLED_NoConfigDuringNormal) { | 1107 TEST_F(SyncSchedulerTest, DISABLED_NoConfigDuringNormal) { |
| 1152 } | 1108 } |
| 1153 | 1109 |
| 1154 // Test that starting the syncer thread without a valid connection doesn't | 1110 // Test that starting the syncer thread without a valid connection doesn't |
| 1155 // break things when a connection is detected. | 1111 // break things when a connection is detected. |
| 1156 TEST_F(SyncSchedulerTest, StartWhenNotConnected) { | 1112 TEST_F(SyncSchedulerTest, StartWhenNotConnected) { |
| 1157 connection()->SetServerNotReachable(); | 1113 connection()->SetServerNotReachable(); |
| 1158 connection()->UpdateConnectionStatus(); | 1114 connection()->UpdateConnectionStatus(); |
| 1159 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 1115 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
| 1160 .WillOnce(Invoke(sessions::test_util::SimulateConnectionFailure)) | 1116 .WillOnce(Invoke(sessions::test_util::SimulateConnectionFailure)) |
| 1161 .WillOnce(QuitLoopNowAction()); | 1117 .WillOnce(QuitLoopNowAction()); |
| 1162 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1118 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1163 MessageLoop::current()->RunAllPending(); | |
| 1164 | 1119 |
| 1165 scheduler()->ScheduleNudge( | 1120 scheduler()->ScheduleNudgeAsync( |
| 1166 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); | 1121 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); |
| 1167 // Should save the nudge for until after the server is reachable. | 1122 // Should save the nudge for until after the server is reachable. |
| 1168 MessageLoop::current()->RunAllPending(); | 1123 MessageLoop::current()->RunAllPending(); |
| 1169 | 1124 |
| 1170 connection()->SetServerReachable(); | 1125 connection()->SetServerReachable(); |
| 1171 connection()->UpdateConnectionStatus(); | 1126 connection()->UpdateConnectionStatus(); |
| 1172 scheduler()->OnConnectionStatusChange(); | 1127 scheduler()->OnConnectionStatusChange(); |
| 1173 MessageLoop::current()->RunAllPending(); | 1128 MessageLoop::current()->RunAllPending(); |
| 1174 } | 1129 } |
| 1175 | 1130 |
| 1176 TEST_F(SyncSchedulerTest, SetsPreviousRoutingInfo) { | 1131 TEST_F(SyncSchedulerTest, SetsPreviousRoutingInfo) { |
| 1177 ModelSafeRoutingInfo info; | 1132 ModelSafeRoutingInfo info; |
| 1178 EXPECT_TRUE(info == context()->previous_session_routing_info()); | 1133 EXPECT_TRUE(info == context()->previous_session_routing_info()); |
| 1179 ModelSafeRoutingInfo expected(context()->routing_info()); | 1134 ModelSafeRoutingInfo expected(context()->routing_info()); |
| 1180 ASSERT_FALSE(expected.empty()); | 1135 ASSERT_FALSE(expected.empty()); |
| 1181 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1); | 1136 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1); |
| 1182 | 1137 |
| 1183 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1138 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1184 RunLoop(); | |
| 1185 | 1139 |
| 1186 scheduler()->ScheduleNudge( | 1140 scheduler()->ScheduleNudgeAsync( |
| 1187 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); | 1141 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(), FROM_HERE); |
| 1188 PumpLoop(); | 1142 PumpLoop(); |
| 1189 // Pump again to run job. | 1143 // Pump again to run job. |
| 1190 PumpLoop(); | 1144 PumpLoop(); |
| 1191 | 1145 |
| 1192 StopSyncScheduler(); | 1146 StopSyncScheduler(); |
| 1193 | 1147 |
| 1194 EXPECT_TRUE(expected == context()->previous_session_routing_info()); | 1148 EXPECT_TRUE(expected == context()->previous_session_routing_info()); |
| 1195 } | 1149 } |
| 1196 | 1150 |
| 1197 } // namespace browser_sync | 1151 } // namespace browser_sync |
| OLD | NEW |