OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "sync/engine/sync_session_job.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/time.h" | |
10 #include "sync/internal_api/public/base/model_type_invalidation_map.h" | |
11 #include "sync/sessions/sync_session.h" | |
12 #include "sync/sessions/sync_session_context.h" | |
13 #include "sync/sessions/test_util.h" | |
14 #include "sync/test/engine/fake_model_worker.h" | |
15 #include "testing/gmock/include/gmock/gmock.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 using base::TimeTicks; | |
19 | |
20 namespace syncer { | |
21 | |
22 using sessions::SyncSession; | |
23 | |
24 class MockDelegate : public SyncSession::Delegate { | |
25 public: | |
26 MockDelegate() {} | |
27 ~MockDelegate() {} | |
28 | |
29 MOCK_METHOD0(IsSyncingCurrentlySilenced, bool()); | |
30 MOCK_METHOD1(OnReceivedShortPollIntervalUpdate, void(const base::TimeDelta&)); | |
31 MOCK_METHOD1(OnReceivedLongPollIntervalUpdate ,void(const base::TimeDelta&)); | |
32 MOCK_METHOD1(OnReceivedSessionsCommitDelay, void(const base::TimeDelta&)); | |
33 MOCK_METHOD1(OnSyncProtocolError, void(const sessions::SyncSessionSnapshot&)); | |
34 MOCK_METHOD0(OnShouldStopSyncingPermanently, void()); | |
35 MOCK_METHOD1(OnSilencedUntil, void(const base::TimeTicks&)); | |
36 }; | |
37 | |
38 class SyncSessionJobTest : public testing::Test { | |
39 public: | |
40 SyncSessionJobTest() : config_params_callback_invoked_(false) {} | |
41 virtual void SetUp() { | |
42 routes_.clear(); | |
43 workers_.clear(); | |
44 config_params_callback_invoked_ = false; | |
45 routes_[BOOKMARKS] = GROUP_PASSIVE; | |
46 scoped_refptr<ModelSafeWorker> passive_worker( | |
47 new FakeModelWorker(GROUP_PASSIVE)); | |
48 workers_.push_back(passive_worker); | |
49 std::vector<ModelSafeWorker*> workers; | |
50 GetWorkers(&workers); | |
51 context_.reset(new sessions::SyncSessionContext( | |
52 NULL, // |connection_manager| | |
53 NULL, // |directory| | |
54 workers, | |
55 NULL, // |extensions_activity_monitor| | |
56 NULL, // |throttled_data_type_tracker| | |
57 std::vector<SyncEngineEventListener*>(), | |
58 NULL, // |debug_info_getter| | |
59 NULL, // |traffic_recorder| | |
60 true /* |enable keystore encryption| */)); | |
61 context_->set_routing_info(routes_); | |
62 } | |
63 | |
64 scoped_ptr<SyncSession> NewLocalSession() { | |
65 sessions::SyncSourceInfo info( | |
66 sync_pb::GetUpdatesCallerInfo::LOCAL, ModelTypeInvalidationMap()); | |
67 return scoped_ptr<SyncSession>(new SyncSession(context_.get(), | |
68 &delegate_, info, context_->routing_info(), | |
69 context_->workers())); | |
70 } | |
71 | |
72 void GetWorkers(std::vector<ModelSafeWorker*>* out) const { | |
73 out->clear(); | |
74 for (std::vector<scoped_refptr<ModelSafeWorker> >::const_iterator it = | |
75 workers_.begin(); it != workers_.end(); ++it) { | |
76 out->push_back(it->get()); | |
77 } | |
78 } | |
79 | |
80 void ConfigurationParamsCallback() { | |
81 config_params_callback_invoked_ = true; | |
82 } | |
83 | |
84 bool config_params_callback_invoked() const { | |
85 return config_params_callback_invoked_; | |
86 } | |
87 | |
88 sessions::SyncSessionContext* context() { return context_.get(); } | |
89 SyncSession::Delegate* delegate() { return &delegate_; } | |
90 const ModelSafeRoutingInfo& routes() { return routes_; } | |
91 | |
92 // Checks that the two jobs are "clones" as defined by SyncSessionJob, | |
93 // minus location and SyncSession checking, for reuse in different | |
94 // scenarios. | |
95 void ExpectClonesBase(SyncSessionJob* job, SyncSessionJob* clone) { | |
96 EXPECT_EQ(job->purpose(), clone->purpose()); | |
97 EXPECT_EQ(job->scheduled_start(), clone->scheduled_start()); | |
98 EXPECT_EQ(job->start_step(), clone->start_step()); | |
99 EXPECT_EQ(job->end_step(), clone->end_step()); | |
100 EXPECT_FALSE(clone->is_canary()); | |
101 } | |
102 | |
103 private: | |
104 scoped_ptr<sessions::SyncSessionContext> context_; | |
105 std::vector<scoped_refptr<ModelSafeWorker> > workers_; | |
106 MockDelegate delegate_; | |
107 ModelSafeRoutingInfo routes_; | |
108 bool config_params_callback_invoked_; | |
109 }; | |
110 | |
111 TEST_F(SyncSessionJobTest, Clone) { | |
112 SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(), | |
113 NewLocalSession().Pass(), ConfigurationParams(), FROM_HERE); | |
114 | |
115 sessions::test_util::SimulateSuccess(job1.mutable_session(), | |
116 job1.start_step(), | |
117 job1.end_step()); | |
118 job1.Finish(false); | |
119 ModelSafeRoutingInfo new_routes; | |
120 new_routes[AUTOFILL] = GROUP_PASSIVE; | |
121 context()->set_routing_info(new_routes); | |
122 const tracked_objects::Location from_here1(FROM_HERE); | |
123 scoped_ptr<SyncSessionJob> clone1 = job1.Clone(); | |
124 scoped_ptr<SyncSessionJob> clone1_loc = job1.CloneFromLocation(from_here1); | |
125 | |
126 ExpectClonesBase(&job1, clone1.get()); | |
127 ExpectClonesBase(&job1, clone1_loc.get()); | |
128 EXPECT_NE(job1.session(), clone1->session()); | |
129 EXPECT_EQ(job1.session()->routing_info(), | |
130 clone1->session()->routing_info()); | |
131 EXPECT_EQ(job1.from_location().ToString(), | |
132 clone1->from_location().ToString()); | |
133 EXPECT_NE(job1.session(), clone1_loc->session()); | |
134 EXPECT_EQ(job1.session()->routing_info(), | |
135 clone1_loc->session()->routing_info()); | |
136 EXPECT_EQ(from_here1.ToString(), clone1_loc->from_location().ToString()); | |
137 | |
138 context()->set_routing_info(routes()); | |
139 clone1->GrantCanaryPrivilege(); | |
140 sessions::test_util::SimulateSuccess(clone1->mutable_session(), | |
141 clone1->start_step(), | |
142 clone1->end_step()); | |
143 clone1->Finish(false); | |
144 const tracked_objects::Location from_here2(FROM_HERE); | |
145 scoped_ptr<SyncSessionJob> clone2 = clone1->Clone(); | |
146 scoped_ptr<SyncSessionJob> clone2_loc(clone1->CloneFromLocation(from_here2)); | |
147 | |
148 ExpectClonesBase(clone1.get(), clone2.get()); | |
149 ExpectClonesBase(clone1.get(), clone2_loc.get()); | |
150 EXPECT_NE(clone1->session(), clone2->session()); | |
151 EXPECT_EQ(clone1->session()->routing_info(), | |
152 clone2->session()->routing_info()); | |
153 EXPECT_EQ(clone1->from_location().ToString(), | |
154 clone2->from_location().ToString()); | |
155 EXPECT_NE(clone1->session(), clone2->session()); | |
156 EXPECT_EQ(clone1->session()->routing_info(), | |
157 clone2->session()->routing_info()); | |
158 EXPECT_EQ(from_here2.ToString(), clone2_loc->from_location().ToString()); | |
159 | |
160 clone1.reset(); | |
161 clone1_loc.reset(); | |
162 ExpectClonesBase(&job1, clone2.get()); | |
163 EXPECT_NE(job1.session(), clone2->session()); | |
164 EXPECT_EQ(job1.session()->routing_info(), | |
165 clone2->session()->routing_info()); | |
166 EXPECT_EQ(job1.from_location().ToString(), | |
167 clone2->from_location().ToString()); | |
168 } | |
169 | |
170 TEST_F(SyncSessionJobTest, CloneAfterEarlyExit) { | |
171 SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(), | |
172 NewLocalSession().Pass(), ConfigurationParams(), FROM_HERE); | |
173 job1.Finish(true); | |
174 scoped_ptr<SyncSessionJob> job2 = job1.Clone(); | |
175 scoped_ptr<SyncSessionJob> job2_loc = job1.CloneFromLocation(FROM_HERE); | |
176 ExpectClonesBase(&job1, job2.get()); | |
177 ExpectClonesBase(&job1, job2_loc.get()); | |
178 } | |
179 | |
180 TEST_F(SyncSessionJobTest, CloneAndAbandon) { | |
181 scoped_ptr<SyncSession> session = NewLocalSession(); | |
182 SyncSession* session_ptr = session.get(); | |
183 | |
184 SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(), | |
185 session.Pass(), ConfigurationParams(), FROM_HERE); | |
186 ModelSafeRoutingInfo new_routes; | |
187 new_routes[AUTOFILL] = GROUP_PASSIVE; | |
188 context()->set_routing_info(new_routes); | |
189 | |
190 scoped_ptr<SyncSessionJob> clone1 = job1.CloneAndAbandon(); | |
191 ExpectClonesBase(&job1, clone1.get()); | |
192 EXPECT_FALSE(job1.session()); | |
193 EXPECT_EQ(session_ptr, clone1->session()); | |
194 EXPECT_EQ(session_ptr->routing_info(), clone1->session()->routing_info()); | |
195 } | |
196 | |
197 // Tests interaction between Finish and sync cycle success / failure. | |
198 TEST_F(SyncSessionJobTest, Finish) { | |
199 SyncSessionJob job1(SyncSessionJob::NUDGE, TimeTicks::Now(), | |
200 NewLocalSession().Pass(), ConfigurationParams(), FROM_HERE); | |
201 | |
202 sessions::test_util::SimulateSuccess(job1.mutable_session(), | |
203 job1.start_step(), | |
204 job1.end_step()); | |
205 EXPECT_TRUE(job1.Finish(false /* early_exit */)); | |
206 | |
207 scoped_ptr<SyncSessionJob> job2 = job1.Clone(); | |
208 sessions::test_util::SimulateConnectionFailure(job2->mutable_session(), | |
209 job2->start_step(), | |
210 job2->end_step()); | |
211 EXPECT_FALSE(job2->Finish(false)); | |
212 | |
213 scoped_ptr<SyncSessionJob> job3 = job2->Clone(); | |
214 EXPECT_FALSE(job3->Finish(true)); | |
215 } | |
216 | |
217 TEST_F(SyncSessionJobTest, FinishCallsReadyTask) { | |
218 ConfigurationParams params; | |
219 params.ready_task = base::Bind( | |
220 &SyncSessionJobTest::ConfigurationParamsCallback, | |
221 base::Unretained(this)); | |
222 | |
223 sessions::SyncSourceInfo info( | |
224 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, | |
225 ModelTypeInvalidationMap()); | |
226 scoped_ptr<SyncSession> session(new SyncSession(context(), | |
227 delegate(), info, context()->routing_info(), | |
228 context()->workers())); | |
229 | |
230 SyncSessionJob job1(SyncSessionJob::CONFIGURATION, TimeTicks::Now(), | |
231 session.Pass(), params, FROM_HERE); | |
232 sessions::test_util::SimulateSuccess(job1.mutable_session(), | |
233 job1.start_step(), | |
234 job1.end_step()); | |
235 job1.Finish(false); | |
236 EXPECT_TRUE(config_params_callback_invoked()); | |
237 } | |
238 | |
239 } // namespace syncer | |
OLD | NEW |