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 |