15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/backoff_delay_provider.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/sync_scheduler_impl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/syncer.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "sync/internal_api/public/base/cancelation_signal.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/internal_api/public/base/model_type_test_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/sessions/test_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/callback_counter.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/fake_model_worker.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/mock_connection_manager.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/test/engine/mock_nudge_handler.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/test_directory_setter_upper.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/test/mock_invalidation.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "sync/util/extensions_activity.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AtLeast;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Invoke;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::WithArg;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing testing::WithArgs;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::WithoutArgs;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sessions::SyncSession;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sessions::SyncSessionContext;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::GetUpdatesCallerInfo;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockSyncer : public Syncer {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  MockSyncer();
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet,
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                     const sessions::NudgeTracker&,
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                     sessions::SyncSession*));
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  MOCK_METHOD3(ConfigureSyncShare,
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)               bool(ModelTypeSet,
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    sync_pb::GetUpdatesCallerInfo::GetUpdatesSource,
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    SyncSession*));
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, sessions::SyncSession*));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)MockSyncer::MockSyncer()
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  : Syncer(NULL) {}
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)typedef std::vector<TimeTicks> SyncShareTimes;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuitLoopNow() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We use QuitNow() instead of Quit() as the latter may get stalled
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // indefinitely in the presence of repeated timers with low delays
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and a slow test (e.g., ThrottlingDoesThrottle [which has a poll
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delay of 5ms] run under TSAN on the trybots).
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->QuitNow();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunLoop() {
71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->Run();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PumpLoop() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do it this way instead of RunAllPending to pump loop exactly once
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (necessary in the presence of timers; see comment in
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // QuitLoopNow).
78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&QuitLoopNow));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PumpLoopFor(base::TimeDelta time) {
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Allow the loop to run for the specified amount of time.
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      FROM_HERE, base::Bind(&QuitLoopNow), time);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RunLoop();
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelSafeRoutingInfo TypesToRoutingInfo(ModelTypeSet types) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelSafeRoutingInfo routes;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routes[iter.Get()] = GROUP_PASSIVE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return routes;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kMinNumSamples = 5;
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Test harness for the SyncScheduler.  Test the delays and backoff timers used
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// in response to various events.
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// These tests execute in real time with real timers.  We try to keep the
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// delays short, but there is a limit to how short we can make them.  The
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// timers on some platforms (ie. Windows) have a timer resolution greater than
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 1ms.  Using 1ms delays may result in test flakiness.
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// See crbug.com/402212 for more info.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncSchedulerTest : public testing::Test {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncSchedulerTest() : syncer_(NULL), delay_(NULL), weak_ptr_factory_(this) {}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockDelayProvider : public BackoffDelayProvider {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockDelayProvider() : BackoffDelayProvider(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TimeDelta::FromSeconds(kInitialBackoffRetrySeconds),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dir_maker_.SetUp();
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    syncer_ = new testing::StrictMock<MockSyncer>();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delay_ = NULL;
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    extensions_activity_ = new ExtensionsActivity();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    routing_info_[THEMES] = GROUP_UI;
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    routing_info_[TYPED_URLS] = GROUP_DB;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[THEMES] = GROUP_UI;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[NIGORI] = GROUP_PASSIVE;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.clear();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_UI)));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_DB)));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_PASSIVE)));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    connection_.reset(new MockConnectionManager(directory(),
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                &cancelation_signal_));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    connection_->SetServerReachable();
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    model_type_registry_.reset(
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new ModelTypeRegistry(workers_, directory(), &mock_nudge_handler_));
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_.reset(new SyncSessionContext(
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            connection_.get(), directory(),
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            extensions_activity_.get(),
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            std::vector<SyncEngineEventListener*>(), NULL,
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            model_type_registry_.get(),
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            true,  // enable keystore encryption
152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            false,  // force enable pre-commit GU avoidance
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "fake_invalidator_client_id"));
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context_->SetRoutingInfo(routing_info_);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->set_notifications_enabled(true);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->set_account_name("Test");
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler_.reset(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new SyncSchedulerImpl("TestSyncScheduler",
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            BackoffDelayProvider::FromDefaults(),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            context(),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            syncer_));
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scheduler_->SetDefaultNudgeDelay(default_delay());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncSchedulerImpl* scheduler() { return scheduler_.get(); }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelSafeRoutingInfo& routing_info() { return routing_info_; }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSyncer* syncer() { return syncer_; }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockDelayProvider* delay() { return delay_; }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnectionManager* connection() { return connection_.get(); }
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TimeDelta default_delay() { return TimeDelta::FromSeconds(0); }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta timeout() {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TestTimeouts::action_timeout();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PumpLoop();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler_.reset();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PumpLoop();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dir_maker_.TearDown();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void AnalyzePollRun(const SyncShareTimes& times, size_t min_num_samples,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TimeTicks& optimal_start, const TimeDelta& poll_interval) {
184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_GE(times.size(), min_num_samples);
185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (size_t i = 0; i < times.size(); i++) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeTicks optimal_next_sync = optimal_start + poll_interval * i;
188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_GE(times[i], optimal_next_sync);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoQuitLoopNow() {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuitLoopNow();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartSyncScheduler(SyncScheduler::Mode mode) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler()->Start(mode);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This stops the scheduler synchronously.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StopSyncScheduler() {
202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        FROM_HERE,
204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::Bind(&SyncSchedulerTest::DoQuitLoopNow,
205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunLoop();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool RunAndGetBackoff() {
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ModelTypeSet nudge_types(THEMES);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartSyncScheduler(SyncScheduler::NORMAL_MODE);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunLoop();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return scheduler()->IsBackingOff();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UseMockDelayProvider() {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delay_ = new MockDelayProvider();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler_->delay_provider_.reset(delay_);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncSessionContext* context() { return context_.get(); }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ModelTypeSet GetThrottledTypes() {
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return scheduler_->nudge_tracker_.GetThrottledTypes();
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta GetRetryTimerDelay() {
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(scheduler_->retry_timer_.IsRunning());
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return scheduler_->retry_timer_.GetCurrentDelay();
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static scoped_ptr<InvalidationInterface> BuildInvalidation(
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      int64 version,
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const std::string& payload) {
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return MockInvalidation::Build(version, payload)
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        .PassAs<InvalidationInterface>();
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncable::Directory* directory() {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return dir_maker_.directory();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::MessageLoop loop_;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestDirectorySetterUpper dir_maker_;
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CancelationSignal cancelation_signal_;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockConnectionManager> connection_;
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<ModelTypeRegistry> model_type_registry_;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SyncSessionContext> context_;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SyncSchedulerImpl> scheduler_;
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockNudgeHandler mock_nudge_handler_;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSyncer* syncer_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockDelayProvider* delay_;
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<scoped_refptr<ModelSafeWorker> > workers_;
258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<ExtensionsActivity> extensions_activity_;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelSafeRoutingInfo routing_info_;
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::WeakPtrFactory<SyncSchedulerTest> weak_ptr_factory_;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void RecordSyncShareImpl(SyncShareTimes* times) {
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  times->push_back(TimeTicks::Now());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ACTION_P(RecordSyncShare, times) {
268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RecordSyncShareImpl(times);
269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (base::MessageLoop::current()->is_running())
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuitLoopNow();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ACTION_P2(RecordSyncShareMultiple, times, quit_after) {
275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RecordSyncShareImpl(times);
276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_LE(times->size(), quit_after);
277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (times->size() >= quit_after &&
278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->is_running()) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuitLoopNow();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ACTION_P(StopScheduler, scheduler) {
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->Stop();
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION(AddFailureAndQuitLoopNow) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_FAILURE();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuitLoopNow();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION(QuitLoopNowAction) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuitLoopNow();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test nudge scheduling.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, Nudge) {
301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ModelTypeSet model_types(THEMES);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)))
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure a second, later, nudge is unaffected by first (no coalescing).
317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  model_types.Remove(THEMES);
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  model_types.Put(TYPED_URLS);
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure a regular config command is scheduled fine in the absence of any
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// errors.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, Config) {
330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet model_types(THEMES);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_types,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(model_types),
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop();
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, ready_counter.times_called());
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, retry_counter.times_called());
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulate a failure and make sure the config request is retried.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ConfigWithBackingOff) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
3576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(20)));
358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
35903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet model_types(THEMES);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      RecordSyncShare(&times)))
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_types,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(model_types),
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // RunLoop() will trigger TryCanaryJob which will retry configuration.
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Since retry_task was already called it shouldn't be called again.
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunLoop();
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
388a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
389a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
390a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
392a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, ready_counter.times_called());
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Simuilate SyncSchedulerImpl::Stop being called in the middle of Configure.
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This can happen if server returns NOT_MY_BIRTHDAY.
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SyncSchedulerTest, ConfigWithStop) {
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UseMockDelayProvider();
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
4036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(20)));
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncShareTimes times;
40503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet model_types(THEMES);
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make ConfigureSyncShare call scheduler->Stop(). It is not supposed to call
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // retry_task or dereference configuration params.
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      StopScheduler(scheduler()),
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      RecordSyncShare(&times)));
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ConfigurationParams params(
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      model_types,
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      TypesToRoutingInfo(model_types),
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop();
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, retry_counter.times_called());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Issue a nudge when the config has failed. Make sure both the config and
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nudge are executed.
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) {
43303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet model_types(THEMES);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50)));
437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Request a configure and make sure it fails.
442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_types,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(model_types),
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Ask for a nudge while dealing with repeated configure failure.
460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
46303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(model_types, FROM_HERE);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we're not RunLoop()ing for the NUDGE we just scheduled, but
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the first retry attempt from the config job (after
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // waiting ~+/- 50ms).
468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Let the next configure retry succeed.
472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now change the mode so nudge can execute.
478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
480a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that nudges are coalesced.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeCoalescing) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
489a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
492a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
49303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3(THEMES);
49403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  TimeTicks optimal_time = TimeTicks::Now() + default_delay();
49503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types1, FROM_HERE);
49603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types2, FROM_HERE);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(1U, times.size());
500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[0], optimal_time);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
50803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types3, FROM_HERE);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that nudges are coalesced.
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
516a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
519a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
52003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a huge time delay.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta delay = TimeDelta::FromDays(1);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::map<ModelType, TimeDelta> delay_map;
52603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  delay_map[types1.First().Get()] = delay;
52703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->OnReceivedCustomNudgeDelays(delay_map);
52803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types1, FROM_HERE);
52903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types2, FROM_HERE);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks min_time = TimeTicks::Now();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks max_time = TimeTicks::Now() + delay;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the sync happened at the right time.
538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(1U, times.size());
539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[0], min_time);
540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_LE(times[0], max_time);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test nudge scheduling.
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeWithStates) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SyncShareTimes times1;
548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
55058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                      RecordSyncShare(&times1)))
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
552116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scheduler()->ScheduleInvalidationNudge(
55303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      THEMES, BuildInvalidation(10, "test"), FROM_HERE);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure a second, later, nudge is unaffected by first (no coalescing).
559a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
562a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scheduler()->ScheduleInvalidationNudge(
56403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      TYPED_URLS, BuildInvalidation(10, "test2"), FROM_HERE);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that polling works as expected.
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, Polling) {
570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillRepeatedly(
574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                RecordSyncShareMultiple(&times, kMinNumSamples)));
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the short poll interval is used.
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, PollNotificationsDisabled) {
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillRepeatedly(
595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                RecordSyncShareMultiple(&times, kMinNumSamples)));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->SetNotificationsEnabled(false);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that polling intervals are updated when needed.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, PollIntervalUpdate) {
613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll1(TimeDelta::FromMilliseconds(120));
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll2(TimeDelta::FromMilliseconds(30));
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll1);
617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArgs<0,1>(
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              sessions::test_util::SimulatePollIntervalUpdate(poll2)),
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(
623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                WithArg<1>(
625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    RecordSyncShareMultiple(&times, kMinNumSamples))));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll2);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that no syncing occurs when throttled.
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) {
63903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet types(THEMES);
6406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(20));
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta throttle(TimeDelta::FromMinutes(10));
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          WithArg<2>(sessions::test_util::SimulateThrottled(throttle)),
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(AddFailureAndQuitLoopNow());
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      types,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(types),
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop();
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingExpiresFromPoll) {
673a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(15));
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::testing::InSequence seq;
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)),
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillRepeatedly(
686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                RecordSyncShareMultiple(&times, kMinNumSamples)));
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
696a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingExpiresFromNudge) {
700a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ::testing::InSequence seq;
706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(DoAll(
708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)),
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Return(true)))
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .RetiresOnSaturation();
711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      QuitLoopNowAction()));
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet types(THEMES);
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
71703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get TrySyncSessionJob called
7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(scheduler()->IsCurrentlyThrottled());
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunLoop();
7237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsCurrentlyThrottled());
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopSyncScheduler();
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) {
729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ::testing::InSequence seq;
735a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(DoAll(
737a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)),
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Return(true)))
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .RetiresOnSaturation();
740a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      QuitLoopNowAction()));
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet types(THEMES);
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConfigurationParams params(
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      types,
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TypesToRoutingInfo(types),
753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop();
757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, ready_counter.times_called());
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, retry_counter.times_called());
7597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(scheduler()->IsCurrentlyThrottled());
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunLoop();
7627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsCurrentlyThrottled());
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopSyncScheduler();
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(SyncSchedulerTest, TypeThrottlingBlocksNudge) {
76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UseMockDelayProvider();
76990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
77003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      .WillRepeatedly(Return(default_delay()));
77190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
77390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromSeconds(60));
77490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet types(THEMES);
77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ::testing::InSequence seq;
779eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(DoAll(
781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<2>(
78290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              sessions::test_util::SimulateTypesThrottled(types, throttle1)),
78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          Return(true)))
78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
78703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get TrySyncSessionJob called
7907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(GetThrottledTypes().HasAll(types));
79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This won't cause a sync cycle because the types are throttled.
79303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PumpLoop();
79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StopSyncScheduler();
79790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(SyncSchedulerTest, TypeThrottlingDoesBlockOtherSources) {
80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UseMockDelayProvider();
80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
80203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      .WillRepeatedly(Return(default_delay()));
80390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
804a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromSeconds(60));
80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
80903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet throttled_types(THEMES);
81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const ModelTypeSet unthrottled_types(PREFERENCES);
81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
81290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ::testing::InSequence seq;
813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
81490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(DoAll(
815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<2>(
81690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              sessions::test_util::SimulateTypesThrottled(
81790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  throttled_types, throttle1)),
81890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          Return(true)))
81990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
82090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
82190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
82203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(throttled_types, FROM_HERE);
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get TrySyncSessionJob called
8257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types));
82690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Ignore invalidations for throttled types.
828116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scheduler()->ScheduleInvalidationNudge(
82903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      THEMES, BuildInvalidation(10, "test"), FROM_HERE);
8307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PumpLoop();
83190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Ignore refresh requests for throttled types.
83303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalRefreshRequest(throttled_types, FROM_HERE);
8347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PumpLoop();
835a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
836a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
83790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Local nudges for non-throttled types will trigger a sync.
839a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
840a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
841a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                            RecordSyncShare(&times)));
84203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(unthrottled_types, FROM_HERE);
84390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunLoop();
844a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
84690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StopSyncScheduler();
84790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test nudges / polls don't run in config mode and config tasks do.
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ConfigurationMode) {
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(15));
852a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet nudge_types(TYPED_URLS);
85803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
85903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet config_types(THEMES);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
863a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
864a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
865a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)))
866a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .RetiresOnSaturation();
867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
868f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      config_types,
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(config_types),
873f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
874f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, ready_counter.times_called());
878f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, retry_counter.times_called());
879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
880a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Switch to NORMAL_MODE to ensure NUDGES were properly saved and run.
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(TimeDelta::FromDays(1));
884a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
887a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tim): Figure out how to remove this dangerous need to reset
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // routing info between mode switches.
8915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  context()->SetRoutingInfo(routing_info());
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest {
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncSchedulerTest::SetUp();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UseMockDelayProvider();
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*delay(), GetDelay(_))
9036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        .WillRepeatedly(Return(TimeDelta::FromMilliseconds(10)));
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() {
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopSyncScheduler();
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncSchedulerTest::TearDown();
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the sycner fail during commit.  Expect that the scheduler enters
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// backoff.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnce) {
915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      QuitLoopNowAction()));
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RunAndGetBackoff());
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail during download updates and succeed on the first
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// retry.  Expect that this clears the backoff state.
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadOnceThenSucceed) {
924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateDownloadUpdatesFailed),
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      QuitLoopNowAction()));
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunAndGetBackoff());
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail during commit and succeed on the first retry.  Expect
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that this clears the backoff state.
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnceThenSucceed) {
936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateCommitFailed),
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
940eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      QuitLoopNowAction()));
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunAndGetBackoff());
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail to download updates and fail again on the retry.
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Expect this will leave the scheduler in backoff.
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadTwice) {
948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateDownloadUpdatesFailed),
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(DoAll(
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Invoke(sessions::test_util::SimulateDownloadUpdatesFailed),
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              QuitLoopNowAction()));
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RunAndGetBackoff());
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail to get the encryption key yet succeed in downloading
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// updates. Expect this will leave the scheduler in backoff.
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) {
961a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed),
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(DoAll(
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed),
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              QuitLoopNowAction()));
968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
97003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ModelTypeSet types(THEMES);
971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ConfigurationParams params(
974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetUpdatesCallerInfo::RECONFIGURATION,
975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      types,
976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      TypesToRoutingInfo(types),
977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scheduler()->ScheduleConfiguration(params);
980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunLoop();
981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(scheduler()->IsBackingOff());
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that no polls or extraneous nudges occur when in backoff.
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, BackoffDropsJobs) {
987a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
9886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(10));
98903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const ModelTypeSet types(THEMES);
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
994a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
995a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShareMultiple(&times, 1U)));
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_)).
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WillRepeatedly(Return(TimeDelta::FromDays(1)));
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This nudge should fail and put us into backoff.  Thanks to our mock
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetDelay() setup above, this will be a long backoff.
100303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1006a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // From this point forward, no SyncShare functions should be invoked.
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Wait a while (10x poll interval) so a few poll jobs will be attempted.
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PumpLoopFor(poll * 10);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Try (and fail) to schedule a nudge.
101303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(types, FROM_HERE);
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(delay());
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_)).Times(0);
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      types,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(types),
1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
1030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
10315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop();
1032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
1033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
1034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that backoff is shaping traffic properly with consecutive errors.
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, BackoffElevation) {
1039a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)).Times(kMinNumSamples)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
1044a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          RecordSyncShareMultiple(&times, kMinNumSamples)));
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta first = TimeDelta::FromSeconds(kInitialBackoffRetrySeconds);
10476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const TimeDelta second = TimeDelta::FromMilliseconds(20);
10486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const TimeDelta third = TimeDelta::FromMilliseconds(30);
10496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const TimeDelta fourth = TimeDelta::FromMilliseconds(40);
10506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const TimeDelta fifth = TimeDelta::FromMilliseconds(50);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta sixth = TimeDelta::FromDays(1);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(first)).WillOnce(Return(second))
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(second)).WillOnce(Return(third))
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(third)).WillOnce(Return(fourth))
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(fourth)).WillOnce(Return(fifth))
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(fifth)).WillOnce(Return(sixth));
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again with a nudge.
106603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1069a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(kMinNumSamples, times.size());
1070a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[1] - times[0], second);
1071a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[2] - times[1], third);
1072a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[3] - times[2], fourth);
1073a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[4] - times[3], fifth);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that things go back to normal once a retry makes forward progress.
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, BackoffRelief) {
1078a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta poll(TimeDelta::FromMilliseconds(10));
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const TimeDelta backoff = TimeDelta::FromMilliseconds(10);
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff));
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Optimal start for the post-backoff poll party.
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now();
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1090a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Kick off the test with a failed nudge.
1091a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
1092a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
1093a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
109403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
1096a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_job_time = optimal_start;
1098a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(1U, times.size());
1099a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[0], optimal_job_time);
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The retry succeeds.
1102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
1103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(
1104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              Invoke(sessions::test_util::SimulateNormalSuccess),
1105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              RecordSyncShare(&times)));
1106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunLoop();
1107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  optimal_job_time = optimal_job_time + backoff;
1109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(2U, times.size());
1110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[1], optimal_job_time);
1111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Now let the Poll timer do its thing.
1113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillRepeatedly(DoAll(
1115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              Invoke(sessions::test_util::SimulatePollSuccess),
1116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              RecordSyncShareMultiple(&times, kMinNumSamples)));
1117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunLoop();
1118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
1119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(kMinNumSamples, times.size());
1120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (size_t i = 2; i < times.size(); i++) {
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    optimal_job_time = optimal_job_time + poll;
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
1123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_GE(times[i], optimal_job_time);
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  StopSyncScheduler();
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that poll failures are ignored.  They should have no effect on
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subsequent poll attempts, nor should they trigger a backoff/retry.
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, TransientPollFailure) {
1132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
11336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const TimeDelta poll_interval(TimeDelta::FromMilliseconds(10));
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval);
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider(); // Will cause test failure if backoff is initiated.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollFailed),
1139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)))
1140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
1141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the unsucessful poll. The failed poll should not trigger backoff.
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsBackingOff());
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the successful poll.
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsBackingOff());
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that starting the syncer thread without a valid connection doesn't
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// break things when a connection is detected.
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, StartWhenNotConnected) {
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerNotReachable();
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
1159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure),
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Return(true)))
1162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    Return(true)));
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should save the nudge for until after the server is reachable.
1168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerReachable();
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
1173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ServerConnectionChangeDuringBackoff) {
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0)));
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerNotReachable();
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure),
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Return(true)))
1188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    Return(true)));
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
119103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
11925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // Run the nudge, that will fail and schedule a quick retry.
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(scheduler()->IsBackingOff());
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before we run the scheduled canary, trigger a server connection change.
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerReachable();
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
1200b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This was supposed to test the scenario where we receive a nudge while a
1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// connection change canary is scheduled, but has not run yet.  Since we've made
1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the connection change canary synchronous, this is no longer possible.
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) {
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0)));
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerNotReachable();
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure),
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Return(true)))
1218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    Return(true)))
1220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    QuitLoopNowAction()));
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
12265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop(); // Run the nudge, that will fail and schedule a quick retry.
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(scheduler()->IsBackingOff());
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before we run the scheduled canary, trigger a server connection change.
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
12315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpLoop();
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerReachable();
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
123403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that we don't crash trying to run two canaries at once if we receive
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// extra connection status change notifications.  See crbug.com/190085.
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) {
1241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillRepeatedly(DoAll(
1243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              Invoke(sessions::test_util::SimulateConfigureConnectionFailure),
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              Return(true)));
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connection()->SetServerNotReachable();
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connection()->UpdateConnectionStatus();
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
124903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ModelTypeSet model_types(THEMES);
1250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
1251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConfigurationParams params(
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model_types,
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TypesToRoutingInfo(model_types),
1256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
1257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();  // Run the nudge, that will fail and schedule a quick retry.
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12667dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) {
1267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
12687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TimeDelta poll(TimeDelta::FromMilliseconds(15));
12697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
12707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ::testing::InSequence seq;
12727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
12735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillRepeatedly(
1274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
12755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                RecordSyncShareMultiple(&times, kMinNumSamples)));
12767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR);
12787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
12797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Run to wait for polling.
12817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RunLoop();
12827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll,
12847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // but after poll finished with auth error from poll timer it should retry
12857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // poll once more
12867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
1288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
12897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scheduler()->OnCredentialsUpdated();
12907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK);
12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StopSyncScheduler();
12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SyncSchedulerTest, SuccessfulRetry) {
12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncShareTimes times;
12996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler()->OnReceivedGuRetryDelay(delay);
13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(delay, GetRetryTimerDelay());
13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
13045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(
1305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
13065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                RecordSyncShare(&times)));
13075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Run to wait for retrying.
13095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
13105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StopSyncScheduler();
13125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SyncSchedulerTest, FailedRetry) {
13155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UseMockDelayProvider();
13165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
13176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(10)));
13185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
13205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
13225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler()->OnReceivedGuRetryDelay(delay);
13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(
1326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulateDownloadUpdatesFailed),
13275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                QuitLoopNowAction()));
13285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Run to wait for retrying.
13305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
13315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(scheduler()->IsBackingOff());
1333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
13345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(
1335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
13365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                QuitLoopNowAction()));
13375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Run to wait for second retrying.
13395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
13405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StopSyncScheduler();
13425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ACTION_P2(VerifyRetryTimerDelay, scheduler_test, expected_delay) {
13455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_delay, scheduler_test->GetRetryTimerDelay());
13465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SyncSchedulerTest, ReceiveNewRetryDelay) {
13495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
13505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SyncShareTimes times;
13525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(100);
13535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(200);
13545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE);
13565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler()->OnReceivedGuRetryDelay(delay1);
13575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(delay1, GetRetryTimerDelay());
13585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
13605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(DoAll(
13615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          WithoutArgs(VerifyRetryTimerDelay(this, delay1)),
13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          WithArg<2>(sessions::test_util::SimulateGuRetryDelayCommand(delay2)),
13635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          RecordSyncShare(&times)));
13645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Run nudge GU.
13665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
13675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(delay2, GetRetryTimerDelay());
13685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
1370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
13715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      RecordSyncShare(&times)));
13725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Run to wait for retrying.
13745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop();
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StopSyncScheduler();
13777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
13787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
1380