| Index: sync/engine/sync_session_job_unittest.cc
|
| diff --git a/sync/engine/sync_session_job_unittest.cc b/sync/engine/sync_session_job_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..466dffae2c9598fc99e20716de3d48b1c979b950
|
| --- /dev/null
|
| +++ b/sync/engine/sync_session_job_unittest.cc
|
| @@ -0,0 +1,239 @@
|
| +// Copyright (c) 2012 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 "sync/engine/sync_session_job.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/time.h"
|
| +#include "sync/internal_api/public/base/model_type_invalidation_map.h"
|
| +#include "sync/sessions/sync_session.h"
|
| +#include "sync/sessions/sync_session_context.h"
|
| +#include "sync/sessions/test_util.h"
|
| +#include "sync/test/engine/fake_model_worker.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using base::TimeTicks;
|
| +
|
| +namespace syncer {
|
| +
|
| +using sessions::SyncSession;
|
| +
|
| +class MockDelegate : public SyncSession::Delegate {
|
| + public:
|
| + MockDelegate() {}
|
| + ~MockDelegate() {}
|
| +
|
| + MOCK_METHOD0(IsSyncingCurrentlySilenced, bool());
|
| + MOCK_METHOD1(OnReceivedShortPollIntervalUpdate, void(const base::TimeDelta&));
|
| + MOCK_METHOD1(OnReceivedLongPollIntervalUpdate ,void(const base::TimeDelta&));
|
| + MOCK_METHOD1(OnReceivedSessionsCommitDelay, void(const base::TimeDelta&));
|
| + MOCK_METHOD1(OnSyncProtocolError, void(const sessions::SyncSessionSnapshot&));
|
| + MOCK_METHOD0(OnShouldStopSyncingPermanently, void());
|
| + MOCK_METHOD1(OnSilencedUntil, void(const base::TimeTicks&));
|
| +};
|
| +
|
| +class SyncSessionJobTest : public testing::Test {
|
| + public:
|
| + SyncSessionJobTest() : config_params_callback_invoked_(false) {}
|
| + virtual void SetUp() {
|
| + routes_.clear();
|
| + workers_.clear();
|
| + config_params_callback_invoked_ = false;
|
| + routes_[BOOKMARKS] = GROUP_PASSIVE;
|
| + scoped_refptr<ModelSafeWorker> passive_worker(
|
| + new FakeModelWorker(GROUP_PASSIVE));
|
| + workers_.push_back(passive_worker);
|
| + std::vector<ModelSafeWorker*> workers;
|
| + GetWorkers(&workers);
|
| + context_.reset(new sessions::SyncSessionContext(
|
| + NULL, // |connection_manager|
|
| + NULL, // |directory|
|
| + workers,
|
| + NULL, // |extensions_activity_monitor|
|
| + NULL, // |throttled_data_type_tracker|
|
| + std::vector<SyncEngineEventListener*>(),
|
| + NULL, // |debug_info_getter|
|
| + NULL, // |traffic_recorder|
|
| + true /* |enable keystore encryption| */));
|
| + context_->set_routing_info(routes_);
|
| + }
|
| +
|
| + scoped_ptr<SyncSession> NewLocalSession() {
|
| + sessions::SyncSourceInfo info(
|
| + sync_pb::GetUpdatesCallerInfo::LOCAL, ModelTypeInvalidationMap());
|
| + return scoped_ptr<SyncSession>(new SyncSession(context_.get(),
|
| + &delegate_, info, context_->routing_info(),
|
| + context_->workers()));
|
| + }
|
| +
|
| + void GetWorkers(std::vector<ModelSafeWorker*>* out) const {
|
| + out->clear();
|
| + for (std::vector<scoped_refptr<ModelSafeWorker> >::const_iterator it =
|
| + workers_.begin(); it != workers_.end(); ++it) {
|
| + out->push_back(it->get());
|
| + }
|
| + }
|
| +
|
| + void ConfigurationParamsCallback() {
|
| + config_params_callback_invoked_ = true;
|
| + }
|
| +
|
| + bool config_params_callback_invoked() const {
|
| + return config_params_callback_invoked_;
|
| + }
|
| +
|
| + sessions::SyncSessionContext* context() { return context_.get(); }
|
| + SyncSession::Delegate* delegate() { return &delegate_; }
|
| + const ModelSafeRoutingInfo& routes() { return routes_; }
|
| +
|
| + // Checks that the two jobs are "clones" as defined by SyncSessionJob,
|
| + // minus location and SyncSession checking, for reuse in different
|
| + // scenarios.
|
| + void ExpectClonesBase(SyncSessionJob* job, SyncSessionJob* clone) {
|
| + EXPECT_EQ(job->purpose(), clone->purpose());
|
| + EXPECT_EQ(job->scheduled_start(), clone->scheduled_start());
|
| + EXPECT_EQ(job->start_step(), clone->start_step());
|
| + EXPECT_EQ(job->end_step(), clone->end_step());
|
| + EXPECT_FALSE(clone->is_canary());
|
| + }
|
| +
|
| + private:
|
| + scoped_ptr<sessions::SyncSessionContext> context_;
|
| + std::vector<scoped_refptr<ModelSafeWorker> > workers_;
|
| + MockDelegate delegate_;
|
| + ModelSafeRoutingInfo routes_;
|
| + bool config_params_callback_invoked_;
|
| +};
|
| +
|
| +TEST_F(SyncSessionJobTest, Clone) {
|
| + SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(),
|
| + NewLocalSession().Pass(), ConfigurationParams(), FROM_HERE);
|
| +
|
| + sessions::test_util::SimulateSuccess(job1.mutable_session(),
|
| + job1.start_step(),
|
| + job1.end_step());
|
| + job1.Finish(false);
|
| + ModelSafeRoutingInfo new_routes;
|
| + new_routes[AUTOFILL] = GROUP_PASSIVE;
|
| + context()->set_routing_info(new_routes);
|
| + const tracked_objects::Location from_here1(FROM_HERE);
|
| + scoped_ptr<SyncSessionJob> clone1 = job1.Clone();
|
| + scoped_ptr<SyncSessionJob> clone1_loc = job1.CloneFromLocation(from_here1);
|
| +
|
| + ExpectClonesBase(&job1, clone1.get());
|
| + ExpectClonesBase(&job1, clone1_loc.get());
|
| + EXPECT_NE(job1.session(), clone1->session());
|
| + EXPECT_EQ(job1.session()->routing_info(),
|
| + clone1->session()->routing_info());
|
| + EXPECT_EQ(job1.from_location().ToString(),
|
| + clone1->from_location().ToString());
|
| + EXPECT_NE(job1.session(), clone1_loc->session());
|
| + EXPECT_EQ(job1.session()->routing_info(),
|
| + clone1_loc->session()->routing_info());
|
| + EXPECT_EQ(from_here1.ToString(), clone1_loc->from_location().ToString());
|
| +
|
| + context()->set_routing_info(routes());
|
| + clone1->GrantCanaryPrivilege();
|
| + sessions::test_util::SimulateSuccess(clone1->mutable_session(),
|
| + clone1->start_step(),
|
| + clone1->end_step());
|
| + clone1->Finish(false);
|
| + const tracked_objects::Location from_here2(FROM_HERE);
|
| + scoped_ptr<SyncSessionJob> clone2 = clone1->Clone();
|
| + scoped_ptr<SyncSessionJob> clone2_loc(clone1->CloneFromLocation(from_here2));
|
| +
|
| + ExpectClonesBase(clone1.get(), clone2.get());
|
| + ExpectClonesBase(clone1.get(), clone2_loc.get());
|
| + EXPECT_NE(clone1->session(), clone2->session());
|
| + EXPECT_EQ(clone1->session()->routing_info(),
|
| + clone2->session()->routing_info());
|
| + EXPECT_EQ(clone1->from_location().ToString(),
|
| + clone2->from_location().ToString());
|
| + EXPECT_NE(clone1->session(), clone2->session());
|
| + EXPECT_EQ(clone1->session()->routing_info(),
|
| + clone2->session()->routing_info());
|
| + EXPECT_EQ(from_here2.ToString(), clone2_loc->from_location().ToString());
|
| +
|
| + clone1.reset();
|
| + clone1_loc.reset();
|
| + ExpectClonesBase(&job1, clone2.get());
|
| + EXPECT_NE(job1.session(), clone2->session());
|
| + EXPECT_EQ(job1.session()->routing_info(),
|
| + clone2->session()->routing_info());
|
| + EXPECT_EQ(job1.from_location().ToString(),
|
| + clone2->from_location().ToString());
|
| +}
|
| +
|
| +TEST_F(SyncSessionJobTest, CloneAfterEarlyExit) {
|
| + SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(),
|
| + NewLocalSession().Pass(), ConfigurationParams(), FROM_HERE);
|
| + job1.Finish(true);
|
| + scoped_ptr<SyncSessionJob> job2 = job1.Clone();
|
| + scoped_ptr<SyncSessionJob> job2_loc = job1.CloneFromLocation(FROM_HERE);
|
| + ExpectClonesBase(&job1, job2.get());
|
| + ExpectClonesBase(&job1, job2_loc.get());
|
| +}
|
| +
|
| +TEST_F(SyncSessionJobTest, CloneAndAbandon) {
|
| + scoped_ptr<SyncSession> session = NewLocalSession();
|
| + SyncSession* session_ptr = session.get();
|
| +
|
| + SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(),
|
| + session.Pass(), ConfigurationParams(), FROM_HERE);
|
| + ModelSafeRoutingInfo new_routes;
|
| + new_routes[AUTOFILL] = GROUP_PASSIVE;
|
| + context()->set_routing_info(new_routes);
|
| +
|
| + scoped_ptr<SyncSessionJob> clone1 = job1.CloneAndAbandon();
|
| + ExpectClonesBase(&job1, clone1.get());
|
| + EXPECT_FALSE(job1.session());
|
| + EXPECT_EQ(session_ptr, clone1->session());
|
| + EXPECT_EQ(session_ptr->routing_info(), clone1->session()->routing_info());
|
| +}
|
| +
|
| +// Tests interaction between Finish and sync cycle success / failure.
|
| +TEST_F(SyncSessionJobTest, Finish) {
|
| + SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(),
|
| + NewLocalSession().Pass(), ConfigurationParams(), FROM_HERE);
|
| +
|
| + sessions::test_util::SimulateSuccess(job1.mutable_session(),
|
| + job1.start_step(),
|
| + job1.end_step());
|
| + EXPECT_TRUE(job1.Finish(false /* early_exit */));
|
| +
|
| + scoped_ptr<SyncSessionJob> job2 = job1.Clone();
|
| + sessions::test_util::SimulateConnectionFailure(job2->mutable_session(),
|
| + job2->start_step(),
|
| + job2->end_step());
|
| + EXPECT_FALSE(job2->Finish(false));
|
| +
|
| + scoped_ptr<SyncSessionJob> job3 = job2->Clone();
|
| + EXPECT_FALSE(job3->Finish(true));
|
| +}
|
| +
|
| +TEST_F(SyncSessionJobTest, FinishCallsReadyTask) {
|
| + ConfigurationParams params;
|
| + params.ready_task = base::Bind(
|
| + &SyncSessionJobTest::ConfigurationParamsCallback,
|
| + base::Unretained(this));
|
| +
|
| + sessions::SyncSourceInfo info(
|
| + sync_pb::GetUpdatesCallerInfo::RECONFIGURATION,
|
| + ModelTypeInvalidationMap());
|
| + scoped_ptr<SyncSession> session(new SyncSession(context(),
|
| + delegate(), info, context()->routing_info(),
|
| + context()->workers()));
|
| +
|
| + SyncSessionJob job1(SyncSessionJob::CONFIGURATION, TimeTicks::Now(),
|
| + session.Pass(), params, FROM_HERE);
|
| + sessions::test_util::SimulateSuccess(job1.mutable_session(),
|
| + job1.start_step(),
|
| + job1.end_step());
|
| + job1.Finish(false);
|
| + EXPECT_TRUE(config_params_callback_invoked());
|
| +}
|
| +
|
| +} // namespace syncer
|
|
|