172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file.
472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/waitable_event.h"
672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/test/test_timeouts.h"
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/engine/mock_model_safe_workers.h"
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/engine/syncer.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/engine/syncer_thread.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/sessions/test_util.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/test/sync/engine/mock_connection_manager.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/test/sync/engine/test_directory_setter_upper.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "testing/gtest/include/gtest/gtest.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "testing/gmock/include/gmock/gmock.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing base::TimeDelta;
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing base::TimeTicks;
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::_;
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::AtLeast;
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::DoAll;
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::Eq;
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::Invoke;
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::Mock;
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::Return;
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing testing::WithArg;
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace browser_sync {
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing sessions::SyncSession;
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing sessions::SyncSessionContext;
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing sessions::SyncSessionSnapshot;
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing syncable::ModelTypeBitSet;
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing sync_pb::GetUpdatesCallerInfo;
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass MockSyncer : public Syncer {
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MOCK_METHOD3(SyncShare, void(sessions::SyncSession*, SyncerStep,
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                               SyncerStep));
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Used when tests want to record syncing activity to examine later.
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct SyncShareRecords {
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::vector<TimeTicks> times;
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::vector<linked_ptr<SyncSessionSnapshot> > snapshots;
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Convenient to use in tests wishing to analyze SyncShare calls over time.
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const size_t kMinNumSamples = 5;
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass SyncerThread2Test : public testing::Test {
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  class MockDelayProvider : public SyncerThread::DelayProvider {
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen   public:
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&));
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  };
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void SetUp() {
5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncdb_.SetUp();
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncer_ = new MockSyncer();
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delay_ = NULL;
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    registrar_.reset(MockModelSafeWorkerRegistrar::PassiveBookmarks());
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    connection_.reset(new MockConnectionManager(syncdb_.manager(), "Test"));
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    connection_->SetServerReachable();
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    context_ = new SyncSessionContext(connection_.get(), syncdb_.manager(),
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        registrar_.get(), std::vector<SyncEngineEventListener*>());
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    context_->set_notifications_enabled(true);
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    context_->set_account_name("Test");
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncer_thread_.reset(new SyncerThread(context_, syncer_));
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void SetUpWithTypes(syncable::ModelTypeBitSet types) {
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncdb_.SetUp();
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncer_ = new MockSyncer();
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delay_ = NULL;
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    registrar_.reset(MockModelSafeWorkerRegistrar::PassiveForTypes(types));
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    connection_.reset(new MockConnectionManager(syncdb_.manager(), "Test"));
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    connection_->SetServerReachable();
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    context_ = new SyncSessionContext(connection_.get(), syncdb_.manager(),
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        registrar_.get(), std::vector<SyncEngineEventListener*>());
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    context_->set_notifications_enabled(true);
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    context_->set_account_name("Test");
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncer_thread_.reset(new SyncerThread(context_, syncer_));
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncerThread* syncer_thread() { return syncer_thread_.get(); }
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockSyncer* syncer() { return syncer_; }
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockDelayProvider* delay() { return delay_; }
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockConnectionManager* connection() { return connection_.get(); }
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta zero() { return TimeDelta::FromSeconds(0); }
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta timeout() {
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms());
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void TearDown() {
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncer_thread()->Stop();
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncdb_.TearDown();
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void AnalyzePollRun(const SyncShareRecords& records, size_t min_num_samples,
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      const TimeTicks& optimal_start, const TimeDelta& poll_interval) {
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::vector<TimeTicks>& data(records.times);
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_GE(data.size(), min_num_samples);
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    for (size_t i = 0; i < data.size(); i++) {
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      TimeTicks optimal_next_sync = optimal_start + poll_interval * i;
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      EXPECT_GE(data[i], optimal_next_sync);
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      EXPECT_EQ(GetUpdatesCallerInfo::PERIODIC,
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                records.snapshots[i]->source.updates_source);
10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool GetBackoffAndResetTest(base::WaitableEvent* done) {
11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncable::ModelTypeBitSet nudge_types;
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, nudge_types,
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   FROM_HERE);
11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    done->TimedWait(timeout());
11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    TearDown();
11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    done->Reset();
11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    Mock::VerifyAndClearExpectations(syncer());
11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool backing_off = syncer_thread()->IsBackingOff();
12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    SetUp();
12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    UseMockDelayProvider();
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_CALL(*delay(), GetDelay(_))
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1)));
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return backing_off;
12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void UseMockDelayProvider() {
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delay_ = new MockDelayProvider();
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncer_thread_->delay_provider_.reset(delay_);
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void PostSignalTask(base::WaitableEvent* done) {
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncer_thread_->thread_.message_loop()->PostTask(FROM_HERE,
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NewRunnableFunction(&SyncerThread2Test::SignalWaitableEvent, done));
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void FlushLastTask(base::WaitableEvent* done) {
13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PostSignalTask(done);
13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    done->TimedWait(timeout());
14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    done->Reset();
14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  static void SignalWaitableEvent(base::WaitableEvent* event) {
14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    event->Signal();
14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static void QuitMessageLoop() {
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    MessageLoop::current()->Quit();
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Compare a ModelTypeBitSet to a ModelTypePayloadMap, ignoring
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // payload values.
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool CompareModelTypeBitSetToModelTypePayloadMap(
15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      const syncable::ModelTypeBitSet& lhs,
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const syncable::ModelTypePayloadMap& rhs) {
15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    size_t count = 0;
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (syncable::ModelTypePayloadMap::const_iterator i = rhs.begin();
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen         i != rhs.end(); ++i, ++count) {
15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (!lhs.test(i->first))
16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        return false;
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (lhs.count() != count)
16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SyncSessionContext* context() { return context_; }
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private:
17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<SyncerThread> syncer_thread_;
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<MockConnectionManager> connection_;
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncSessionContext* context_;
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockSyncer* syncer_;
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockDelayProvider* delay_;
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<MockModelSafeWorkerRegistrar> registrar_;
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockDirectorySetterUpper syncdb_;
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RecordSyncShareImpl(SyncSession* s, SyncShareRecords* record,
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                         size_t signal_after) {
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  record->times.push_back(TimeTicks::Now());
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  record->snapshots.push_back(make_linked_ptr(new SyncSessionSnapshot(
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      s->TakeSnapshot())));
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return record->times.size() >= signal_after;
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenACTION_P4(RecordSyncShareAndPostSignal, record, signal_after, test, event) {
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (RecordSyncShareImpl(arg0, record, signal_after) && event)
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    test->PostSignalTask(event);
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenACTION_P3(RecordSyncShare, record, signal_after, event) {
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (RecordSyncShareImpl(arg0, record, signal_after) && event)
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    event->Signal();
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenACTION_P(SignalEvent, event) {
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncerThread2Test::SignalWaitableEvent(event);
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test nudge scheduling.
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, Nudge) {
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records;
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::ModelTypeBitSet model_types;
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  model_types[syncable::BOOKMARKS] = true;
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done))))
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .RetiresOnSaturation();
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, model_types,
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, records.snapshots.size());
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      records.snapshots[0]->source.types));
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            records.snapshots[0]->source.updates_source);
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Make sure a second, later, nudge is unaffected by first (no coalescing).
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records2;
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  model_types[syncable::BOOKMARKS] = false;
22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  model_types[syncable::AUTOFILL] = true;
22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          WithArg<0>(RecordSyncShare(&records2, 1U, &done))));
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, model_types,
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, records2.snapshots.size());
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      records2.snapshots[0]->source.types));
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            records2.snapshots[0]->source.updates_source);
23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Make sure a regular config command is scheduled fine in the absence of any
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// errors.
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SyncerThread2Test, Config) {
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done(false, false);
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SyncShareRecords records;
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::ModelTypeBitSet model_types;
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  model_types[syncable::BOOKMARKS] = true;
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done))));
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleConfig(model_types);
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done.TimedWait(timeout());
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, records.snapshots.size());
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      records.snapshots[0]->source.types));
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::FIRST_UPDATE,
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            records.snapshots[0]->source.updates_source);
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Simulate a failure and make sure the config request is retried.
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SyncerThread2Test, ConfigWithBackingOff) {
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done(false, false);
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent* dummy = NULL;
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UseMockDelayProvider();
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(_))
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1)));
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SyncShareRecords records;
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::ModelTypeBitSet model_types;
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  model_types[syncable::BOOKMARKS] = true;
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, dummy))))
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done))));
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleConfig(model_types);
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done.TimedWait(timeout());
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2U, records.snapshots.size());
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      records.snapshots[1]->source.types));
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION,
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            records.snapshots[1]->source.updates_source);
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Issue 2 config commands. Second one right after the first has failed
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// and make sure LATEST is executed.
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SyncerThread2Test, MultipleConfigWithBackingOff) {
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::ModelTypeBitSet model_types1, model_types2;
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  model_types1[syncable::BOOKMARKS] = true;
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  model_types2[syncable::AUTOFILL] = true;
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetUpWithTypes(model_types1 | model_types2);
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done(false, false);
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done1(false, false);
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent* dummy = NULL;
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UseMockDelayProvider();
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(_))
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(30)));
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SyncShareRecords records;
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, dummy))))
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done1))))
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done))));
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleConfig(model_types1);
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // done1 indicates the first config failed.
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done1.TimedWait(timeout());
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleConfig(model_types2);
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done.TimedWait(timeout());
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(3U, records.snapshots.size());
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types2,
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      records.snapshots[2]->source.types));
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::FIRST_UPDATE,
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            records.snapshots[2]->source.updates_source);
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Issue a nudge when the config has failed. Make sure both the config and
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// nudge are executed.
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SyncerThread2Test, NudgeWithConfigWithBackingOff) {
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::ModelTypeBitSet model_types;
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  model_types[syncable::BOOKMARKS] = true;
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done(false, false);
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done1(false, false);
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done2(false, false);
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent* dummy = NULL;
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UseMockDelayProvider();
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(_))
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50)));
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SyncShareRecords records;
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, dummy))))
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done1))))
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done2))))
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done))));
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleConfig(model_types);
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done1.TimedWait(timeout());
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, model_types,
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // done2 indicates config suceeded. Now change the mode so nudge can execute.
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done2.TimedWait(timeout());
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done.TimedWait(timeout());
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(4U, records.snapshots.size());
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      records.snapshots[2]->source.types));
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION,
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            records.snapshots[2]->source.updates_source);
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      records.snapshots[3]->source.types));
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            records.snapshots[3]->source.updates_source);
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
38372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that nudges are coalesced.
38472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, NudgeCoalescing) {
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
38772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords r;
38872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
39072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&r, 1U, &done))));
39172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::ModelTypeBitSet types1, types2, types3;
39272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types1[syncable::BOOKMARKS] = true;
39372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types2[syncable::AUTOFILL] = true;
39472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types3[syncable::THEMES] = true;
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TimeDelta delay = TimeDelta::FromMilliseconds(
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TestTimeouts::tiny_timeout_ms());
39772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeTicks optimal_time = TimeTicks::Now() + delay;
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(delay, NUDGE_SOURCE_UNKNOWN, types1,
399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, types2,
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
40272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
40372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
40472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, r.snapshots.size());
40572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_GE(r.times[0], optimal_time);
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(
407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      types1 | types2, r.snapshots[0]->source.types));
408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
40972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            r.snapshots[0]->source.updates_source);
41072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
41172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords r2;
41272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
41372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
41472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&r2, 1U, &done))));
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_NOTIFICATION, types3,
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
41772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
41872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, r2.snapshots.size());
419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(types3,
42072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      r2.snapshots[0]->source.types));
42172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION,
42272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            r2.snapshots[0]->source.updates_source);
42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test nudge scheduling.
42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, NudgeWithPayloads) {
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
42872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
42972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records;
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::ModelTypePayloadMap model_types_with_payloads;
43172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  model_types_with_payloads[syncable::BOOKMARKS] = "test";
43272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          WithArg<0>(RecordSyncShare(&records, 1U, &done))))
43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .RetiresOnSaturation();
43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->ScheduleNudgeWithPayloads(zero(), NUDGE_SOURCE_LOCAL,
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      model_types_with_payloads, FROM_HERE);
43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
44072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
44172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, records.snapshots.size());
44272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(model_types_with_payloads, records.snapshots[0]->source.types);
44372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
44472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            records.snapshots[0]->source.updates_source);
44572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
44672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Make sure a second, later, nudge is unaffected by first (no coalescing).
44772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records2;
44872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  model_types_with_payloads.erase(syncable::BOOKMARKS);
44972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  model_types_with_payloads[syncable::AUTOFILL] = "test2";
45072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
45272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          WithArg<0>(RecordSyncShare(&records2, 1U, &done))));
45372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->ScheduleNudgeWithPayloads(zero(), NUDGE_SOURCE_LOCAL,
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      model_types_with_payloads, FROM_HERE);
45572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
45772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, records2.snapshots.size());
45872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(model_types_with_payloads, records2.snapshots[0]->source.types);
45972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
46072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            records2.snapshots[0]->source.updates_source);
46172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
46272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
46372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that nudges are coalesced.
46472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, NudgeWithPayloadsCoalescing) {
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
46672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
46772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords r;
46872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
46972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
47072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&r, 1U, &done))));
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::ModelTypePayloadMap types1, types2, types3;
47272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types1[syncable::BOOKMARKS] = "test1";
47372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types2[syncable::AUTOFILL] = "test2";
47472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types3[syncable::THEMES] = "test3";
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TimeDelta delay = TimeDelta::FromMilliseconds(
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TestTimeouts::tiny_timeout_ms());
47772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeTicks optimal_time = TimeTicks::Now() + delay;
47872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->ScheduleNudgeWithPayloads(delay, NUDGE_SOURCE_UNKNOWN,
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      types1, FROM_HERE);
48072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->ScheduleNudgeWithPayloads(zero(), NUDGE_SOURCE_LOCAL,
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      types2, FROM_HERE);
48272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
48372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
48472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, r.snapshots.size());
48572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_GE(r.times[0], optimal_time);
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::ModelTypePayloadMap coalesced_types;
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::CoalescePayloads(&coalesced_types, types1);
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncable::CoalescePayloads(&coalesced_types, types2);
48972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(coalesced_types, r.snapshots[0]->source.types);
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
49172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            r.snapshots[0]->source.updates_source);
49272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
49372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords r2;
49472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
49572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
49672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&r2, 1U, &done))));
49772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->ScheduleNudgeWithPayloads(zero(), NUDGE_SOURCE_NOTIFICATION,
498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      types3, FROM_HERE);
49972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
50072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1U, r2.snapshots.size());
50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(types3, r2.snapshots[0]->source.types);
50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION,
50372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            r2.snapshots[0]->source.updates_source);
50472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
50572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
50672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that polling works as expected.
50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, Polling) {
50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records;
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
51172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll_interval);
51272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples))
51372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&records, kMinNumSamples, &done))));
51572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
51672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
51872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
51972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval);
52272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
52372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that the short poll interval is used.
52572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, PollNotificationsDisabled) {
52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records;
52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedShortPollIntervalUpdate(poll_interval);
53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->set_notifications_enabled(false);
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples))
53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&records, kMinNumSamples, &done))));
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
53572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
53872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
53972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval);
54172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that polling intervals are updated when needed.
54472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, PollIntervalUpdate) {
54572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records;
54672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
54772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll1(TimeDelta::FromMilliseconds(120));
54872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll2(TimeDelta::FromMilliseconds(30));
54972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll1);
55072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(AtLeast(kMinNumSamples))
55172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(WithArg<0>(
55272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          sessions::test_util::SimulatePollIntervalUpdate(poll2)))
55372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
55472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&records, kMinNumSamples, &done))));
55572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
55672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2;
557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
55872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
55972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
56072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AnalyzePollRun(records, kMinNumSamples, optimal_start, poll2);
56272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
56372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that a sync session is run through to completion.
56572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, HasMoreToSync) {
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
56772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
56972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateHasMoreToSync))
57072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
57172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                      SignalEvent(&done)));
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(),
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
57472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
57572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // If more nudges are scheduled, they'll be waited on by TearDown, and would
57672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // cause our expectation to break.
57772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
57872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
57972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that no syncing occurs when throttled.
58072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, ThrottlingDoesThrottle) {
58172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::ModelTypeBitSet types;
58272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types[syncable::BOOKMARKS] = true;
58372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
58472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll(TimeDelta::FromMilliseconds(5));
58572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta throttle(TimeDelta::FromMinutes(10));
58672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
58772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
58872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(WithArg<0>(sessions::test_util::SimulateThrottled(throttle)));
58972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, types,
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
59372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FlushLastTask(&done);
59472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
596dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncer_thread()->ScheduleConfig(types);
59772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FlushLastTask(&done);
59872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
59972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
60072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, ThrottlingExpires) {
60172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords records;
60272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
60372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll(TimeDelta::FromMilliseconds(15));
60472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta throttle1(TimeDelta::FromMilliseconds(150));
60572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta throttle2(TimeDelta::FromMinutes(10));
60672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
60772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
60872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ::testing::InSequence seq;
60972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
61072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(WithArg<0>(sessions::test_util::SimulateThrottled(throttle1)))
61172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .RetiresOnSaturation();
61272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
61372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
61472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen           WithArg<0>(RecordSyncShare(&records, kMinNumSamples, &done))));
61572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
61672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1;
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
61872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
61972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
62072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AnalyzePollRun(records, kMinNumSamples, optimal_start, poll);
62272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
62372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test nudges / polls don't run in config mode and config tasks do.
62572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, ConfigurationMode) {
62672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll(TimeDelta::FromMilliseconds(15));
627dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SyncShareRecords records;
62872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
629dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  base::WaitableEvent* dummy = NULL;
63072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
631dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      .WillOnce((Invoke(sessions::test_util::SimulateSuccess),
633dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen           WithArg<0>(RecordSyncShare(&records, 1U, dummy))));
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
63572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::ModelTypeBitSet nudge_types;
63672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  nudge_types[syncable::AUTOFILL] = true;
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, nudge_types,
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, nudge_types,
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
64172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
64272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::ModelTypeBitSet config_types;
64372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  config_types[syncable::BOOKMARKS] = true;
64472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // TODO(tim): This will fail once CONFIGURATION tasks are implemented. Update
64572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // the EXPECT when that happens.
646dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncer_thread()->ScheduleConfig(config_types);
64772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FlushLastTask(&done);
648dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncer_thread()->Stop();
649dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
650dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(1U, records.snapshots.size());
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(config_types,
652dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      records.snapshots[0]->source.types));
65372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
65472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that exponential backoff is properly triggered.
65672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, BackoffTriggers) {
65772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
65872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UseMockDelayProvider();
65972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
66172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateDownloadUpdatesFailed))
66272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
66372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          SignalEvent(&done)));
66472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(GetBackoffAndResetTest(&done));
66572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Note GetBackoffAndResetTest clears mocks and re-instantiates the syncer.
66672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
66772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateCommitFailed))
66872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
66972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          SignalEvent(&done)));
67072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(GetBackoffAndResetTest(&done));
67172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
67272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateDownloadUpdatesFailed))
67372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(
67472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          sessions::test_util::SimulateDownloadUpdatesFailed),
67572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          SignalEvent(&done)));
67672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(GetBackoffAndResetTest(&done));
67772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
67872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateCommitFailed))
67972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
68072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          SignalEvent(&done)));
68172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(GetBackoffAndResetTest(&done));
68272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
68372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateDownloadUpdatesFailed))
68472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateDownloadUpdatesFailed))
68572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
68672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          SignalEvent(&done)));
68772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(GetBackoffAndResetTest(&done));
68872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
68972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateCommitFailed))
69072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateCommitFailed))
69172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
69272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          SignalEvent(&done)));
69372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(GetBackoffAndResetTest(&done));
69472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
69572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
69672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that no polls or extraneous nudges occur when in backoff.
69772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, BackoffDropsJobs) {
69872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords r;
69972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeDelta poll(TimeDelta::FromMilliseconds(5));
70072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
70172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::ModelTypeBitSet types;
70272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  types[syncable::BOOKMARKS] = true;
70372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
70472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UseMockDelayProvider();
70572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
70672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(2)
70772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
70872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          RecordSyncShareAndPostSignal(&r, 2U, this, &done)));
70972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(_))
71072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(Return(TimeDelta::FromDays(1)));
71172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
71372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(done.TimedWait(timeout()));
71472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.Reset();
71572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
71672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Mock::VerifyAndClearExpectations(syncer());
71772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2U, r.snapshots.size());
71872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::PERIODIC,
71972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            r.snapshots[0]->source.updates_source);
72072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION,
72172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            r.snapshots[1]->source.updates_source);
72272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
72372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1)
72472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
72572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          RecordSyncShareAndPostSignal(&r, 1U, this, &done)));
72672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
72772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We schedule a nudge with enough delay (10X poll interval) that at least
72872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // one or two polls would have taken place.  The nudge should succeed.
729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(poll * 10, NUDGE_SOURCE_LOCAL, types,
730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
73172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(done.TimedWait(timeout()));
73272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.Reset();
73372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
73472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Mock::VerifyAndClearExpectations(syncer());
73572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Mock::VerifyAndClearExpectations(delay());
73672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(3U, r.snapshots.size());
73772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
73872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            r.snapshots[2]->source.updates_source);
73972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
74072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(0);
74172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(_)).Times(0);
74272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
744dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncer_thread()->ScheduleConfig(types);
74572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FlushLastTask(&done);
74672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, types,
749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, types,
751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
75272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FlushLastTask(&done);
75372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
75472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
75572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that backoff is shaping traffic properly with consecutive errors.
75672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, BackoffElevation) {
75772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords r;
75872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta poll(TimeDelta::FromMilliseconds(10));
75972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
76072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
76172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UseMockDelayProvider();
76272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
76372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta first = TimeDelta::FromSeconds(1);
76472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta second = TimeDelta::FromMilliseconds(10);
76572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta third = TimeDelta::FromMilliseconds(20);
76672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta fourth = TimeDelta::FromMilliseconds(30);
76772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta fifth = TimeDelta::FromDays(1);
76872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
76972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(kMinNumSamples)
77072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
77172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          RecordSyncShareAndPostSignal(&r, kMinNumSamples, this, &done)));
77272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
77372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(Eq(first))).WillOnce(Return(second))
77472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .RetiresOnSaturation();
77572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(Eq(second))).WillOnce(Return(third))
77672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .RetiresOnSaturation();
77772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(Eq(third))).WillOnce(Return(fourth))
77872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .RetiresOnSaturation();
77972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(Eq(fourth))).WillOnce(Return(fifth));
78072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
781ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
78272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(done.TimedWait(timeout()));
78372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
78472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_GE(r.times[2] - r.times[1], second);
78572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_GE(r.times[3] - r.times[2], third);
78672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_GE(r.times[4] - r.times[3], fourth);
78772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
78872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
78972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that things go back to normal once a canary task makes forward progress
79072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// following a succession of failures.
79172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, BackoffRelief) {
79272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SyncShareRecords r;
79372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta poll(TimeDelta::FromMilliseconds(10));
79472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
79572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
79672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UseMockDelayProvider();
79772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
79872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta backoff = TimeDelta::FromMilliseconds(100);
79972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
80072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_))
80172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateCommitFailed))
80272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillOnce(Invoke(sessions::test_util::SimulateCommitFailed))
80372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
80472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          RecordSyncShareAndPostSignal(&r, kMinNumSamples, this, &done)));
80572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff));
80672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
80772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Optimal start for the post-backoff poll party.
80872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TimeTicks optimal_start = TimeTicks::Now() + poll + backoff;
809ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
81072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
81172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
81272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
81372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check for healthy polling after backoff is relieved.
81472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Can't use AnalyzePollRun because first sync is a continuation. Bleh.
81572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (size_t i = 0; i < r.times.size(); i++) {
81672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
81772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    TimeTicks optimal_next_sync = optimal_start + poll * i;
81872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_GE(r.times[i], optimal_next_sync);
81972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_EQ(i == 0 ? GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION
82072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                     : GetUpdatesCallerInfo::PERIODIC,
82172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              r.snapshots[i]->source.updates_source);
82272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
82372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
82472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
82572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, GetRecommendedDelay) {
82672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_LE(TimeDelta::FromSeconds(0),
82772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            SyncerThread::GetRecommendedDelay(TimeDelta::FromSeconds(0)));
82872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_LE(TimeDelta::FromSeconds(1),
82972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            SyncerThread::GetRecommendedDelay(TimeDelta::FromSeconds(1)));
83072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_LE(TimeDelta::FromSeconds(50),
83172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            SyncerThread::GetRecommendedDelay(TimeDelta::FromSeconds(50)));
83272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_LE(TimeDelta::FromSeconds(10),
83372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            SyncerThread::GetRecommendedDelay(TimeDelta::FromSeconds(10)));
83472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(TimeDelta::FromSeconds(kMaxBackoffSeconds),
83572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            SyncerThread::GetRecommendedDelay(
83672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                TimeDelta::FromSeconds(kMaxBackoffSeconds)));
83772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(TimeDelta::FromSeconds(kMaxBackoffSeconds),
83872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            SyncerThread::GetRecommendedDelay(
83972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                TimeDelta::FromSeconds(kMaxBackoffSeconds + 1)));
84072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
84172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
84272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that appropriate syncer steps are requested for each job type.
84372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, SyncerSteps) {
84472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Nudges.
84572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::WaitableEvent done(false, false);
84672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_, SYNCER_BEGIN, SYNCER_END))
84772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .Times(1);
848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(),
850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
85172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FlushLastTask(&done);
85272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
85372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Mock::VerifyAndClearExpectations(syncer());
85472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
85572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // ClearUserData.
85672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_, CLEAR_PRIVATE_DATA, SYNCER_END))
85772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .Times(1);
858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
85972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->ScheduleClearUserData();
86072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FlushLastTask(&done);
86172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
86272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Mock::VerifyAndClearExpectations(syncer());
863dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Configuration.
864dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_, DOWNLOAD_UPDATES, APPLY_UPDATES));
865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
866dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncer_thread()->ScheduleConfig(ModelTypeBitSet());
867dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  FlushLastTask(&done);
868dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncer_thread()->Stop();
869dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  Mock::VerifyAndClearExpectations(syncer());
870dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
87172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Poll.
87272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_, SYNCER_BEGIN, SYNCER_END))
87372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .Times(AtLeast(1))
87472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillRepeatedly(SignalEvent(&done));
87572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const TimeDelta poll(TimeDelta::FromMilliseconds(10));
87672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
87872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.TimedWait(timeout());
87972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncer_thread()->Stop();
88072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Mock::VerifyAndClearExpectations(syncer());
88172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  done.Reset();
88272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
88372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
88472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test config tasks don't run during normal mode.
88572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// TODO(tim): Implement this test and then the functionality!
88672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(SyncerThread2Test, DISABLED_NoConfigDuringNormal) {
88772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
88872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
88972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that starting the syncer thread without a valid connection doesn't
89072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// break things when a connection is detected.
891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SyncerThread2Test, StartWhenNotConnected) {
892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done(false, false);
893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop cur;
894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  connection()->SetServerNotReachable();
895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).WillOnce(SignalEvent(&done));
896ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(),
898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
899ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FlushLastTask(&done);
900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  connection()->SetServerReachable();
902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  cur.PostTask(FROM_HERE, NewRunnableFunction(
903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &SyncerThread2Test::QuitMessageLoop));
904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  cur.Run();
90572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // By now, the server connection event should have been posted to the
907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // SyncerThread.
908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FlushLastTask(&done);
909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  done.TimedWait(timeout());
910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SyncerThread2Test, SetsPreviousRoutingInfo) {
913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent done(false, false);
914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ModelSafeRoutingInfo info;
915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(info == context()->previous_session_routing_info());
916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ModelSafeRoutingInfo expected;
917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  context()->registrar()->GetModelSafeRoutingInfo(&expected);
918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(expected.empty());
919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1);
920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(),
923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 FROM_HERE);
924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FlushLastTask(&done);
925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncer_thread()->Stop();
926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(expected == context()->previous_session_routing_info());
92872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
92972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
93072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}  // namespace browser_sync
93172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
93272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// SyncerThread won't outlive the test!
933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenDISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::SyncerThread2Test);
934