// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/time.h"
#include "chrome/browser/sync/engine/mock_model_safe_workers.h"
#include "chrome/browser/sync/engine/syncer_thread.h"
#include "chrome/browser/sync/sessions/sync_session_context.h"
#include "chrome/browser/sync/sessions/test_util.h"
#include "chrome/test/sync/engine/mock_connection_manager.h"
#include "chrome/test/sync/engine/test_directory_setter_upper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"
using base::TimeDelta;
using base::TimeTicks;
namespace browser_sync {
using sessions::SyncSessionContext;
using browser_sync::Syncer;
class SyncerThread2WhiteboxTest : public testing::Test {
public:
virtual void SetUp() {
syncdb_.SetUp();
Syncer* syncer = new Syncer();
registrar_.reset(MockModelSafeWorkerRegistrar::PassiveBookmarks());
context_ = new SyncSessionContext(connection_.get(), syncdb_.manager(),
registrar_.get(), std::vector<SyncEngineEventListener*>());
context_->set_notifications_enabled(true);
context_->set_account_name("Test");
syncer_thread_.reset(new SyncerThread(context_, syncer));
}
virtual void TearDown() {
syncdb_.TearDown();
}
void SetMode(SyncerThread::Mode mode) {
syncer_thread_->mode_ = mode;
}
void SetLastSyncedTime(base::TimeTicks ticks) {
syncer_thread_->last_sync_session_end_time_ = ticks;
}
void SetServerConnection(bool connected) {
syncer_thread_->server_connection_ok_ = connected;
}
void ResetWaitInterval() {
syncer_thread_->wait_interval_.reset();
}
void SetWaitIntervalToThrottled() {
syncer_thread_->wait_interval_.reset(new SyncerThread::WaitInterval(
SyncerThread::WaitInterval::THROTTLED, TimeDelta::FromSeconds(1)));
}
void SetWaitIntervalToExponentialBackoff() {
syncer_thread_->wait_interval_.reset(
new SyncerThread::WaitInterval(
SyncerThread::WaitInterval::EXPONENTIAL_BACKOFF,
TimeDelta::FromSeconds(1)));
}
SyncerThread::JobProcessDecision DecideOnJob(
const SyncerThread::SyncSessionJob& job) {
return syncer_thread_->DecideOnJob(job);
}
void InitializeSyncerOnNormalMode() {
SetMode(SyncerThread::NORMAL_MODE);
ResetWaitInterval();
SetServerConnection(true);
SetLastSyncedTime(base::TimeTicks::Now());
}
SyncerThread::JobProcessDecision CreateAndDecideJob(
SyncerThread::SyncSessionJob::SyncSessionJobPurpose purpose) {
struct SyncerThread::SyncSessionJob job;
job.purpose = purpose;
job.scheduled_start = TimeTicks::Now();
return DecideOnJob(job);
}
protected:
scoped_ptr<SyncerThread> syncer_thread_;
private:
scoped_ptr<MockConnectionManager> connection_;
SyncSessionContext* context_;
//MockDelayProvider* delay_;
scoped_ptr<MockModelSafeWorkerRegistrar> registrar_;
MockDirectorySetterUpper syncdb_;
};
TEST_F(SyncerThread2WhiteboxTest, SaveNudge) {
InitializeSyncerOnNormalMode();
// Now set the mode to configure.
SetMode(SyncerThread::CONFIGURATION_MODE);
SyncerThread::JobProcessDecision decision =
CreateAndDecideJob(SyncerThread::SyncSessionJob::NUDGE);
EXPECT_EQ(decision, SyncerThread::SAVE);
}
TEST_F(SyncerThread2WhiteboxTest, ContinueNudge) {
InitializeSyncerOnNormalMode();
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::NUDGE);
EXPECT_EQ(decision, SyncerThread::CONTINUE);
}
TEST_F(SyncerThread2WhiteboxTest, DropPoll) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::CONFIGURATION_MODE);
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::POLL);
EXPECT_EQ(decision, SyncerThread::DROP);
}
TEST_F(SyncerThread2WhiteboxTest, ContinuePoll) {
InitializeSyncerOnNormalMode();
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::POLL);
EXPECT_EQ(decision, SyncerThread::CONTINUE);
}
TEST_F(SyncerThread2WhiteboxTest, ContinueConfiguration) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::CONFIGURATION_MODE);
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::CONFIGURATION);
EXPECT_EQ(decision, SyncerThread::CONTINUE);
}
TEST_F(SyncerThread2WhiteboxTest, SaveConfigurationWhileThrottled) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::CONFIGURATION_MODE);
SetWaitIntervalToThrottled();
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::CONFIGURATION);
EXPECT_EQ(decision, SyncerThread::SAVE);
}
TEST_F(SyncerThread2WhiteboxTest, SaveNudgeWhileThrottled) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::CONFIGURATION_MODE);
SetWaitIntervalToThrottled();
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::NUDGE);
EXPECT_EQ(decision, SyncerThread::SAVE);
}
TEST_F(SyncerThread2WhiteboxTest, ContinueClearUserDataUnderAllCircumstances) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::CONFIGURATION_MODE);
SetWaitIntervalToThrottled();
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::CLEAR_USER_DATA);
EXPECT_EQ(decision, SyncerThread::CONTINUE);
SetMode(SyncerThread::NORMAL_MODE);
SetWaitIntervalToExponentialBackoff();
decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::CLEAR_USER_DATA);
EXPECT_EQ(decision, SyncerThread::CONTINUE);
}
TEST_F(SyncerThread2WhiteboxTest, ContinueNudgeWhileExponentialBackOff) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::NORMAL_MODE);
SetWaitIntervalToExponentialBackoff();
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::NUDGE);
EXPECT_EQ(decision, SyncerThread::CONTINUE);
}
TEST_F(SyncerThread2WhiteboxTest, DropNudgeWhileExponentialBackOff) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::NORMAL_MODE);
SetWaitIntervalToExponentialBackoff();
syncer_thread_->wait_interval_->had_nudge = true;
SyncerThread::JobProcessDecision decision = CreateAndDecideJob(
SyncerThread::SyncSessionJob::NUDGE);
EXPECT_EQ(decision, SyncerThread::DROP);
}
TEST_F(SyncerThread2WhiteboxTest, ContinueCanaryJobConfig) {
InitializeSyncerOnNormalMode();
SetMode(SyncerThread::CONFIGURATION_MODE);
SetWaitIntervalToExponentialBackoff();
struct SyncerThread::SyncSessionJob job;
job.purpose = SyncerThread::SyncSessionJob::CONFIGURATION;
job.scheduled_start = TimeTicks::Now();
job.is_canary_job = true;
SyncerThread::JobProcessDecision decision = DecideOnJob(job);
EXPECT_EQ(decision, SyncerThread::CONTINUE);
}
} // namespace browser_sync
// SyncerThread won't outlive the test!
DISABLE_RUNNABLE_METHOD_REFCOUNT(
browser_sync::SyncerThread2WhiteboxTest);