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"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/notifier/invalidation_util.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/notifier/object_id_invalidation_map.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/sessions/test_util.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/callback_counter.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/fake_model_worker.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/mock_connection_manager.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/test_directory_setter_upper.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;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sessions::SyncSession;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sessions::SyncSessionContext;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::GetUpdatesCallerInfo;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockSyncer : public Syncer {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  MockSyncer();
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet,
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                     const sessions::NudgeTracker&,
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                     sessions::SyncSession*));
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  MOCK_METHOD3(ConfigureSyncShare,
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)               bool(ModelTypeSet,
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    sync_pb::GetUpdatesCallerInfo::GetUpdatesSource,
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    SyncSession*));
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, sessions::SyncSession*));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)MockSyncer::MockSyncer()
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  : Syncer(NULL) {}
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)typedef std::vector<TimeTicks> SyncShareTimes;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuitLoopNow() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We use QuitNow() instead of Quit() as the latter may get stalled
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // indefinitely in the presence of repeated timers with low delays
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and a slow test (e.g., ThrottlingDoesThrottle [which has a poll
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delay of 5ms] run under TSAN on the trybots).
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->QuitNow();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunLoop() {
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->Run();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PumpLoop() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do it this way instead of RunAllPending to pump loop exactly once
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (necessary in the presence of timers; see comment in
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // QuitLoopNow).
77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&QuitLoopNow));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PumpLoopFor(base::TimeDelta time) {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Allow the loop to run for the specified amount of time.
83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      FROM_HERE, base::Bind(&QuitLoopNow), time);
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RunLoop();
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelSafeRoutingInfo TypesToRoutingInfo(ModelTypeSet types) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelSafeRoutingInfo routes;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routes[iter.Get()] = GROUP_PASSIVE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return routes;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convenient to use in tests wishing to analyze SyncShare calls over time.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kMinNumSamples = 5;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncSchedulerTest : public testing::Test {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SyncSchedulerTest() : syncer_(NULL), delay_(NULL), weak_ptr_factory_(this) {}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockDelayProvider : public BackoffDelayProvider {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockDelayProvider() : BackoffDelayProvider(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TimeDelta::FromSeconds(kInitialBackoffRetrySeconds),
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dir_maker_.SetUp();
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    syncer_ = new testing::StrictMock<MockSyncer>();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delay_ = NULL;
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    extensions_activity_ = new ExtensionsActivity();
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[BOOKMARKS] = GROUP_UI;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[AUTOFILL] = GROUP_DB;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[THEMES] = GROUP_UI;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    routing_info_[NIGORI] = GROUP_PASSIVE;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.clear();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_UI)));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_DB)));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_PASSIVE)));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<ModelSafeWorker*> workers;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::vector<scoped_refptr<FakeModelWorker> >::iterator it =
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         workers_.begin(); it != workers_.end(); ++it) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      workers.push_back(it->get());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    connection_.reset(new MockConnectionManager(directory(),
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                &cancelation_signal_));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    connection_->SetServerReachable();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_.reset(new SyncSessionContext(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            connection_.get(), directory(), workers,
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            extensions_activity_.get(),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            std::vector<SyncEngineEventListener*>(), NULL, NULL,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            true,  // enable keystore encryption
142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            false,  // force enable pre-commit GU avoidance
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "fake_invalidator_client_id"));
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->set_routing_info(routing_info_);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->set_notifications_enabled(true);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->set_account_name("Test");
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler_.reset(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new SyncSchedulerImpl("TestSyncScheduler",
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            BackoffDelayProvider::FromDefaults(),
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            context(),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            syncer_));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncSchedulerImpl* scheduler() { return scheduler_.get(); }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelSafeRoutingInfo& routing_info() { return routing_info_; }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSyncer* syncer() { return syncer_; }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockDelayProvider* delay() { return delay_; }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnectionManager* connection() { return connection_.get(); }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta zero() { return TimeDelta::FromSeconds(0); }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta timeout() {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TestTimeouts::action_timeout();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PumpLoop();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler_.reset();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PumpLoop();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dir_maker_.TearDown();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void AnalyzePollRun(const SyncShareTimes& times, size_t min_num_samples,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TimeTicks& optimal_start, const TimeDelta& poll_interval) {
173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_GE(times.size(), min_num_samples);
174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (size_t i = 0; i < times.size(); i++) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeTicks optimal_next_sync = optimal_start + poll_interval * i;
177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_GE(times[i], optimal_next_sync);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoQuitLoopNow() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuitLoopNow();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartSyncScheduler(SyncScheduler::Mode mode) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler()->Start(mode);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This stops the scheduler synchronously.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StopSyncScheduler() {
191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        FROM_HERE,
193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::Bind(&SyncSchedulerTest::DoQuitLoopNow,
194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunLoop();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool RunAndGetBackoff() {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ModelTypeSet nudge_types(BOOKMARKS);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartSyncScheduler(SyncScheduler::NORMAL_MODE);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunLoop();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return scheduler()->IsBackingOff();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UseMockDelayProvider() {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delay_ = new MockDelayProvider();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler_->delay_provider_.reset(delay_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncSessionContext* context() { return context_.get(); }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ModelTypeSet GetThrottledTypes() {
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return scheduler_->nudge_tracker_.GetThrottledTypes();
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncable::Directory* directory() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return dir_maker_.directory();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::MessageLoop loop_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestDirectorySetterUpper dir_maker_;
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CancelationSignal cancelation_signal_;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockConnectionManager> connection_;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SyncSessionContext> context_;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SyncSchedulerImpl> scheduler_;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSyncer* syncer_;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockDelayProvider* delay_;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<scoped_refptr<FakeModelWorker> > workers_;
233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<ExtensionsActivity> extensions_activity_;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelSafeRoutingInfo routing_info_;
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::WeakPtrFactory<SyncSchedulerTest> weak_ptr_factory_;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void RecordSyncShareImpl(SyncShareTimes* times) {
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  times->push_back(TimeTicks::Now());
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ACTION_P(RecordSyncShare, times) {
243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RecordSyncShareImpl(times);
244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (base::MessageLoop::current()->is_running())
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuitLoopNow();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ACTION_P2(RecordSyncShareMultiple, times, quit_after) {
250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RecordSyncShareImpl(times);
251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_LE(times->size(), quit_after);
252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (times->size() >= quit_after &&
253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->is_running()) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuitLoopNow();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ACTION_P(StopScheduler, scheduler) {
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->Stop();
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION(AddFailureAndQuitLoopNow) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_FAILURE();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuitLoopNow();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION(QuitLoopNowAction) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuitLoopNow();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test nudge scheduling.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, Nudge) {
276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet model_types(BOOKMARKS);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)))
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure a second, later, nudge is unaffected by first (no coalescing).
292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_types.Remove(BOOKMARKS);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_types.Put(AUTOFILL);
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure a regular config command is scheduled fine in the absence of any
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// errors.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, Config) {
305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet model_types(BOOKMARKS);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_types,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(model_types),
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
323d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop();
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, ready_counter.times_called());
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, retry_counter.times_called());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulate a failure and make sure the config request is retried.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ConfigWithBackingOff) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1)));
333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet model_types(BOOKMARKS);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      RecordSyncShare(&times)))
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_types,
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(model_types),
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
353d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  RunLoop();
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // RunLoop() will trigger TryCanaryJob which will retry configuration.
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Since retry_task was already called it shouldn't be called again.
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunLoop();
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, ready_counter.times_called());
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Simuilate SyncSchedulerImpl::Stop being called in the middle of Configure.
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This can happen if server returns NOT_MY_BIRTHDAY.
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SyncSchedulerTest, ConfigWithStop) {
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UseMockDelayProvider();
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1)));
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncShareTimes times;
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const ModelTypeSet model_types(BOOKMARKS);
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make ConfigureSyncShare call scheduler->Stop(). It is not supposed to call
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // retry_task or dereference configuration params.
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      StopScheduler(scheduler()),
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      RecordSyncShare(&times)));
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ConfigurationParams params(
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      model_types,
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      TypesToRoutingInfo(model_types),
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
400d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop();
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, retry_counter.times_called());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Issue a nudge when the config has failed. Make sure both the config and
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nudge are executed.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet model_types(BOOKMARKS);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50)));
412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Request a configure and make sure it fails.
417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_types,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(model_types),
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
429d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  RunLoop();
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Ask for a nudge while dealing with repeated configure failure.
435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed),
437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
438b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we're not RunLoop()ing for the NUDGE we just scheduled, but
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the first retry attempt from the config job (after
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // waiting ~+/- 50ms).
443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Let the next configure retry succeed.
447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now change the mode so nudge can execute.
453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
457d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that nudges are coalesced.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeCoalescing) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3(THEMES);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta delay = zero();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_time = TimeTicks::Now() + delay;
471b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE);
472b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(1U, times.size());
476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[0], optimal_time);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
480a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
484b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), types3, FROM_HERE);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that nudges are coalesced.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a huge time delay.
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta delay = TimeDelta::FromDays(1);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
501b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE);
502b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks min_time = TimeTicks::Now();
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks max_time = TimeTicks::Now() + delay;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the sync happened at the right time.
511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(1U, times.size());
512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[0], min_time);
513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_LE(times[0], max_time);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test nudge scheduling.
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, NudgeWithStates) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SyncShareTimes times1;
52158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ObjectIdInvalidationMap invalidations1 =
52258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      BuildInvalidationMap(BOOKMARKS, 10, "test");
523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
52558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                      RecordSyncShare(&times1)))
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler()->ScheduleInvalidationNudge(zero(), invalidations1, FROM_HERE);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure a second, later, nudge is unaffected by first (no coalescing).
533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
53458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ObjectIdInvalidationMap invalidations2 =
53558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      BuildInvalidationMap(AUTOFILL, 10, "test2");
536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
53958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler()->ScheduleInvalidationNudge(zero(), invalidations2, FROM_HERE);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that polling works as expected.
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, Polling) {
545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           RecordSyncShareMultiple(&times, kMinNumSamples)));
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
560a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the short poll interval is used.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, PollNotificationsDisabled) {
565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           RecordSyncShareMultiple(&times, kMinNumSamples)));
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->SetNotificationsEnabled(false);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
581a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that polling intervals are updated when needed.
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, PollIntervalUpdate) {
586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll1(TimeDelta::FromMilliseconds(120));
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll2(TimeDelta::FromMilliseconds(30));
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll1);
590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples))
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArgs<0,1>(
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              sessions::test_util::SimulatePollIntervalUpdate(poll2)),
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                WithArg<1>(
598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    RecordSyncShareMultiple(&times, kMinNumSamples))));
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll2);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the sessions commit delay is updated when needed.
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, SessionsCommitDelay) {
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta delay1(TimeDelta::FromMilliseconds(120));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta delay2(TimeDelta::FromMilliseconds(30));
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedSessionsCommitDelay(delay1);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DoAll(
620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              WithArgs<0,1,2>(
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  sessions::test_util::SimulateSessionsCommitDelayUpdate(
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      delay2)),
623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              Invoke(sessions::test_util::SimulateNormalSuccess),
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              QuitLoopNowAction()));
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(delay1, scheduler()->GetSessionsCommitDelay());
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(delay1, scheduler()->GetSessionsCommitDelay());
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet model_types(BOOKMARKS);
631b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(delay2, scheduler()->GetSessionsCommitDelay());
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that no syncing occurs when throttled.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet types(BOOKMARKS);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(5));
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta throttle(TimeDelta::FromMinutes(10));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          WithArg<2>(sessions::test_util::SimulateThrottled(throttle)),
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(AddFailureAndQuitLoopNow());
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
653b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(
654b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      TimeDelta::FromMicroseconds(1), types, FROM_HERE);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      types,
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(types),
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
668d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop();
669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingExpiresFromPoll) {
675a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(15));
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::testing::InSequence seq;
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)),
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
688a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           RecordSyncShareMultiple(&times, kMinNumSamples)));
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again to wait for polling.
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopSyncScheduler();
697a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalyzePollRun(times, kMinNumSamples, optimal_start, poll);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingExpiresFromNudge) {
701a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ::testing::InSequence seq;
707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(DoAll(
709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)),
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Return(true)))
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .RetiresOnSaturation();
712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      QuitLoopNowAction()));
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ModelTypeSet types(BOOKMARKS);
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
718b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
720d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
721d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get TrySyncSessionJob called
7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(scheduler()->IsCurrentlyThrottled());
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunLoop();
7247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsCurrentlyThrottled());
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopSyncScheduler();
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) {
730a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ::testing::InSequence seq;
736a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(DoAll(
738a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)),
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Return(true)))
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .RetiresOnSaturation();
741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      QuitLoopNowAction()));
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ModelTypeSet types(BOOKMARKS);
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConfigurationParams params(
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      types,
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TypesToRoutingInfo(types),
754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
757d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop();
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, ready_counter.times_called());
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, retry_counter.times_called());
7607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(scheduler()->IsCurrentlyThrottled());
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunLoop();
7637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsCurrentlyThrottled());
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopSyncScheduler();
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(SyncSchedulerTest, TypeThrottlingBlocksNudge) {
76990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UseMockDelayProvider();
77090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
77190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillRepeatedly(Return(zero()));
77290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
77490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromSeconds(60));
77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const ModelTypeSet types(BOOKMARKS);
77890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ::testing::InSequence seq;
780eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
78190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(DoAll(
782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<2>(
78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              sessions::test_util::SimulateTypesThrottled(types, throttle1)),
78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          Return(true)))
78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
78790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
789d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
790d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get TrySyncSessionJob called
7917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(GetThrottledTypes().HasAll(types));
79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This won't cause a sync cycle because the types are throttled.
79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PumpLoop();
79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
79790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StopSyncScheduler();
79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(SyncSchedulerTest, TypeThrottlingDoesBlockOtherSources) {
80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UseMockDelayProvider();
80290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
80390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillRepeatedly(Return(zero()));
80490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
805a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta poll(TimeDelta::FromDays(1));
80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TimeDelta throttle1(TimeDelta::FromSeconds(60));
80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const ModelTypeSet throttled_types(BOOKMARKS);
81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const ModelTypeSet unthrottled_types(PREFERENCES);
81290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
81390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ::testing::InSequence seq;
814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
81590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(DoAll(
816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          WithArg<2>(
81790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              sessions::test_util::SimulateTypesThrottled(
81890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  throttled_types, throttle1)),
81990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          Return(true)))
82090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .RetiresOnSaturation();
82190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
82290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
82390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), throttled_types, FROM_HERE);
824d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
825d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get TrySyncSessionJob called
8267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types));
82790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Ignore invalidations for throttled types.
82958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ObjectIdInvalidationMap invalidations =
83058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      BuildInvalidationMap(BOOKMARKS, 10, "test");
83158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler()->ScheduleInvalidationNudge(zero(), invalidations, FROM_HERE);
8327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PumpLoop();
83390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Ignore refresh requests for throttled types.
83590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->ScheduleLocalRefreshRequest(zero(), throttled_types, FROM_HERE);
8367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PumpLoop();
837a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
838a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
83990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Local nudges for non-throttled types will trigger a sync.
841a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
842a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
843a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                            RecordSyncShare(&times)));
84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), unthrottled_types, FROM_HERE);
84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunLoop();
846a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
84790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StopSyncScheduler();
84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test nudges / polls don't run in config mode and config tasks do.
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ConfigurationMode) {
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(15));
854a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet nudge_types(AUTOFILL);
860b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE);
861b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet config_types(BOOKMARKS);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
866a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess),
867a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)))
868a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .RetiresOnSaturation();
869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
870f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      config_types,
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(config_types),
875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
878d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  RunLoop();
879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, ready_counter.times_called());
880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, retry_counter.times_called());
881f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
882a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Switch to NORMAL_MODE to ensure NUDGES were properly saved and run.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(TimeDelta::FromDays(1));
886a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times2;
887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
889a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times2)));
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tim): Figure out how to remove this dangerous need to reset
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // routing info between mode switches.
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context()->set_routing_info(routing_info());
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
896d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  RunLoop();
897d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest {
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncSchedulerTest::SetUp();
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UseMockDelayProvider();
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*delay(), GetDelay(_))
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1)));
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() {
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopSyncScheduler();
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncSchedulerTest::TearDown();
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the sycner fail during commit.  Expect that the scheduler enters
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// backoff.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnce) {
917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      QuitLoopNowAction()));
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RunAndGetBackoff());
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail during download updates and succeed on the first
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// retry.  Expect that this clears the backoff state.
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadOnceThenSucceed) {
926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateDownloadUpdatesFailed),
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      QuitLoopNowAction()));
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunAndGetBackoff());
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail during commit and succeed on the first retry.  Expect
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that this clears the backoff state.
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnceThenSucceed) {
938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateCommitFailed),
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      QuitLoopNowAction()));
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunAndGetBackoff());
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail to download updates and fail again on the retry.
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Expect this will leave the scheduler in backoff.
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadTwice) {
950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateDownloadUpdatesFailed),
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(DoAll(
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Invoke(sessions::test_util::SimulateDownloadUpdatesFailed),
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              QuitLoopNowAction()));
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RunAndGetBackoff());
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Have the syncer fail to get the encryption key yet succeed in downloading
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// updates. Expect this will leave the scheduler in backoff.
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) {
963a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed),
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Return(true)))
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(DoAll(
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed),
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              QuitLoopNowAction()));
970eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ModelTypeSet types(BOOKMARKS);
973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ConfigurationParams params(
976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetUpdatesCallerInfo::RECONFIGURATION,
977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      types,
978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      TypesToRoutingInfo(types),
979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scheduler()->ScheduleConfiguration(params);
982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunLoop();
983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(scheduler()->IsBackingOff());
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that no polls or extraneous nudges occur when in backoff.
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, BackoffDropsJobs) {
989a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta poll(TimeDelta::FromMilliseconds(5));
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ModelTypeSet types(BOOKMARKS);
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
996a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
997a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShareMultiple(&times, 1U)));
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_)).
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WillRepeatedly(Return(TimeDelta::FromDays(1)));
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This nudge should fail and put us into backoff.  Thanks to our mock
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetDelay() setup above, this will be a long backoff.
1005b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE);
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1008a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // From this point forward, no SyncShare functions should be invoked.
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Wait a while (10x poll interval) so a few poll jobs will be attempted.
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PumpLoopFor(poll * 10);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Try (and fail) to schedule a nudge.
1015b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(1),
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      types,
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE);
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(delay());
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_)).Times(0);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigurationParams params(
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      types,
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TypesToRoutingInfo(types),
1033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
1034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
1035f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
1036d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop();
1037f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0, ready_counter.times_called());
1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1, retry_counter.times_called());
1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that backoff is shaping traffic properly with consecutive errors.
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, BackoffElevation) {
1044a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)).Times(kMinNumSamples)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
1049a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          RecordSyncShareMultiple(&times, kMinNumSamples)));
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta first = TimeDelta::FromSeconds(kInitialBackoffRetrySeconds);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta second = TimeDelta::FromMilliseconds(2);
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta third = TimeDelta::FromMilliseconds(3);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta fourth = TimeDelta::FromMilliseconds(4);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta fifth = TimeDelta::FromMilliseconds(5);
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta sixth = TimeDelta::FromDays(1);
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(first)).WillOnce(Return(second))
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(second)).WillOnce(Return(third))
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(third)).WillOnce(Return(fourth))
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(fourth)).WillOnce(Return(fifth))
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .RetiresOnSaturation();
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(fifth)).WillOnce(Return(sixth));
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run again with a nudge.
1071b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1074a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(kMinNumSamples, times.size());
1075a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[1] - times[0], second);
1076a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[2] - times[1], third);
1077a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[3] - times[2], fourth);
1078a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[4] - times[3], fifth);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that things go back to normal once a retry makes forward progress.
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, BackoffRelief) {
1083a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta poll(TimeDelta::FromMilliseconds(10));
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta backoff = TimeDelta::FromMilliseconds(5);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff));
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Optimal start for the post-backoff poll party.
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_start = TimeTicks::Now();
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Kick off the test with a failed nudge.
1096a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
1097a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
1098a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
1099b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
1101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeTicks optimal_job_time = optimal_start;
1103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(1U, times.size());
1104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[0], optimal_job_time);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The retry succeeds.
1107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
1108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillOnce(DoAll(
1109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              Invoke(sessions::test_util::SimulateNormalSuccess),
1110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              RecordSyncShare(&times)));
1111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunLoop();
1112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  optimal_job_time = optimal_job_time + backoff;
1114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(2U, times.size());
1115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_GE(times[1], optimal_job_time);
1116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Now let the Poll timer do its thing.
1118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      .WillRepeatedly(DoAll(
1120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              Invoke(sessions::test_util::SimulatePollSuccess),
1121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              RecordSyncShareMultiple(&times, kMinNumSamples)));
1122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunLoop();
1123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Mock::VerifyAndClearExpectations(syncer());
1124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(kMinNumSamples, times.size());
1125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (size_t i = 2; i < times.size(); i++) {
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    optimal_job_time = optimal_job_time + poll;
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
1128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_GE(times[i], optimal_job_time);
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  StopSyncScheduler();
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that poll failures are ignored.  They should have no effect on
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subsequent poll attempts, nor should they trigger a backoff/retry.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, TransientPollFailure) {
1137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta poll_interval(TimeDelta::FromMilliseconds(1));
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider(); // Will cause test failure if backoff is initiated.
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
1143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollFailed),
1144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)))
1145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
1146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the unsucessful poll. The failed poll should not trigger backoff.
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsBackingOff());
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the successful poll.
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunLoop();
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(scheduler()->IsBackingOff());
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that starting the syncer thread without a valid connection doesn't
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// break things when a connection is detected.
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, StartWhenNotConnected) {
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerNotReachable();
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
1164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure),
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Return(true)))
1167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    Return(true)));
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should save the nudge for until after the server is reachable.
1173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerReachable();
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
1178b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ServerConnectionChangeDuringBackoff) {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0)));
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerNotReachable();
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure),
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Return(true)))
1193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    Return(true)));
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
1197d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
1198d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // Run the nudge, that will fail and schedule a quick retry.
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(scheduler()->IsBackingOff());
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before we run the scheduled canary, trigger a server connection change.
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerReachable();
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
1205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This was supposed to test the scenario where we receive a nudge while a
1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// connection change canary is scheduled, but has not run yet.  Since we've made
1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the connection change canary synchronous, this is no longer possible.
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) {
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UseMockDelayProvider();
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*delay(), GetDelay(_))
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0)));
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerNotReachable();
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure),
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Return(true)))
1223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    Return(true)))
1225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    QuitLoopNowAction()));
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1230d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // To get PerformDelayedNudge called.
1231d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop(); // Run the nudge, that will fail and schedule a quick retry.
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(scheduler()->IsBackingOff());
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before we run the scheduled canary, trigger a server connection change.
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
1236d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  PumpLoop();
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->SetServerReachable();
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection()->UpdateConnectionStatus();
1239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE);
1240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that we don't crash trying to run two canaries at once if we receive
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// extra connection status change notifications.  See crbug.com/190085.
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) {
1246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_))
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillRepeatedly(DoAll(
1248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              Invoke(sessions::test_util::SimulateConfigureConnectionFailure),
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              Return(true)));
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE);
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connection()->SetServerNotReachable();
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connection()->UpdateConnectionStatus();
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ModelTypeSet model_types(BOOKMARKS);
1255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter ready_counter;
1256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackCounter retry_counter;
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConfigurationParams params(
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetUpdatesCallerInfo::RECONFIGURATION,
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model_types,
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TypesToRoutingInfo(model_types),
1261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)),
1262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter)));
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->ScheduleConfiguration(params);
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler()->OnConnectionStatusChange();
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();  // Run the nudge, that will fail and schedule a quick retry.
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12717dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) {
1272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SyncShareTimes times;
12737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TimeDelta poll(TimeDelta::FromMilliseconds(15));
12747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scheduler()->OnReceivedLongPollIntervalUpdate(poll);
12757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ::testing::InSequence seq;
12777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
12787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
1279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           RecordSyncShareMultiple(&times, kMinNumSamples)));
12807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR);
12827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StartSyncScheduler(SyncScheduler::NORMAL_MODE);
12837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Run to wait for polling.
12857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RunLoop();
12867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll,
12887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // but after poll finished with auth error from poll timer it should retry
12897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // poll once more
12907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*syncer(), PollSyncShare(_,_))
12917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess),
1292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      RecordSyncShare(&times)));
12937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scheduler()->OnCredentialsUpdated();
12947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK);
1295d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  RunLoop();
12967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StopSyncScheduler();
12977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
12987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
1300