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 "chrome/browser/sync/sessions/sync_session.h" | |
6 | |
7 #include "base/compiler_specific.h" | |
8 #include "base/location.h" | |
9 #include "base/memory/ref_counted.h" | |
10 #include "base/message_loop.h" | |
11 #include "chrome/browser/sync/engine/conflict_resolver.h" | |
12 #include "chrome/browser/sync/engine/syncer_types.h" | |
13 #include "chrome/browser/sync/sessions/session_state.h" | |
14 #include "chrome/browser/sync/sessions/status_controller.h" | |
15 #include "chrome/browser/sync/syncable/model_type.h" | |
16 #include "chrome/browser/sync/syncable/syncable.h" | |
17 #include "chrome/browser/sync/syncable/syncable_id.h" | |
18 #include "chrome/browser/sync/test/engine/fake_model_worker.h" | |
19 #include "chrome/browser/sync/test/engine/test_directory_setter_upper.h" | |
20 #include "chrome/browser/sync/test/fake_extensions_activity_monitor.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 | |
23 using syncable::WriteTransaction; | |
24 | |
25 namespace browser_sync { | |
26 namespace sessions { | |
27 namespace { | |
28 | |
29 class SyncSessionTest : public testing::Test, | |
30 public SyncSession::Delegate, | |
31 public ModelSafeWorkerRegistrar { | |
32 public: | |
33 SyncSessionTest() : controller_invocations_allowed_(false) {} | |
34 | |
35 SyncSession* MakeSession() { | |
36 std::vector<ModelSafeWorker*> workers; | |
37 GetWorkers(&workers); | |
38 return new SyncSession(context_.get(), this, SyncSourceInfo(), | |
39 routes_, workers); | |
40 } | |
41 | |
42 virtual void SetUp() { | |
43 context_.reset( | |
44 new SyncSessionContext( | |
45 NULL, NULL, this, &extensions_activity_monitor_, | |
46 std::vector<SyncEngineEventListener*>(), NULL)); | |
47 routes_.clear(); | |
48 routes_[syncable::BOOKMARKS] = GROUP_UI; | |
49 routes_[syncable::AUTOFILL] = GROUP_DB; | |
50 scoped_refptr<ModelSafeWorker> passive_worker( | |
51 new FakeModelWorker(GROUP_PASSIVE)); | |
52 scoped_refptr<ModelSafeWorker> ui_worker( | |
53 new FakeModelWorker(GROUP_UI)); | |
54 scoped_refptr<ModelSafeWorker> db_worker( | |
55 new FakeModelWorker(GROUP_DB)); | |
56 workers_.clear(); | |
57 workers_.push_back(passive_worker); | |
58 workers_.push_back(ui_worker); | |
59 workers_.push_back(db_worker); | |
60 session_.reset(MakeSession()); | |
61 } | |
62 virtual void TearDown() { | |
63 session_.reset(); | |
64 context_.reset(); | |
65 } | |
66 | |
67 virtual void OnSilencedUntil(const base::TimeTicks& silenced_until) OVERRIDE { | |
68 FailControllerInvocationIfDisabled("OnSilencedUntil"); | |
69 } | |
70 virtual bool IsSyncingCurrentlySilenced() OVERRIDE { | |
71 FailControllerInvocationIfDisabled("IsSyncingCurrentlySilenced"); | |
72 return false; | |
73 } | |
74 virtual void OnReceivedLongPollIntervalUpdate( | |
75 const base::TimeDelta& new_interval) OVERRIDE { | |
76 FailControllerInvocationIfDisabled("OnReceivedLongPollIntervalUpdate"); | |
77 } | |
78 virtual void OnReceivedShortPollIntervalUpdate( | |
79 const base::TimeDelta& new_interval) OVERRIDE { | |
80 FailControllerInvocationIfDisabled("OnReceivedShortPollIntervalUpdate"); | |
81 } | |
82 virtual void OnReceivedSessionsCommitDelay( | |
83 const base::TimeDelta& new_delay) OVERRIDE { | |
84 FailControllerInvocationIfDisabled("OnReceivedSessionsCommitDelay"); | |
85 } | |
86 virtual void OnShouldStopSyncingPermanently() OVERRIDE { | |
87 FailControllerInvocationIfDisabled("OnShouldStopSyncingPermanently"); | |
88 } | |
89 virtual void OnSyncProtocolError( | |
90 const sessions::SyncSessionSnapshot& snapshot) { | |
91 FailControllerInvocationIfDisabled("SyncProtocolError"); | |
92 } | |
93 | |
94 // ModelSafeWorkerRegistrar implementation. | |
95 virtual void GetWorkers(std::vector<ModelSafeWorker*>* out) OVERRIDE { | |
96 out->clear(); | |
97 for (std::vector<scoped_refptr<ModelSafeWorker> >::const_iterator it = | |
98 workers_.begin(); it != workers_.end(); ++it) { | |
99 out->push_back(it->get()); | |
100 } | |
101 } | |
102 virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) OVERRIDE { | |
103 *out = routes_; | |
104 } | |
105 | |
106 StatusController* status() { return session_->mutable_status_controller(); } | |
107 protected: | |
108 void FailControllerInvocationIfDisabled(const std::string& msg) { | |
109 if (!controller_invocations_allowed_) | |
110 FAIL() << msg; | |
111 } | |
112 | |
113 syncable::ModelTypeSet ParamsMeaningAllEnabledTypes() { | |
114 syncable::ModelTypeSet request_params( | |
115 syncable::BOOKMARKS, syncable::AUTOFILL); | |
116 return request_params; | |
117 } | |
118 | |
119 syncable::ModelTypeSet ParamsMeaningJustOneEnabledType() { | |
120 return syncable::ModelTypeSet(syncable::AUTOFILL); | |
121 } | |
122 | |
123 MessageLoop message_loop_; | |
124 bool controller_invocations_allowed_; | |
125 scoped_ptr<SyncSession> session_; | |
126 scoped_ptr<SyncSessionContext> context_; | |
127 std::vector<scoped_refptr<ModelSafeWorker> > workers_; | |
128 ModelSafeRoutingInfo routes_; | |
129 FakeExtensionsActivityMonitor extensions_activity_monitor_; | |
130 }; | |
131 | |
132 TEST_F(SyncSessionTest, EnabledGroupsEmpty) { | |
133 routes_.clear(); | |
134 workers_.clear(); | |
135 scoped_ptr<SyncSession> session(MakeSession()); | |
136 std::set<ModelSafeGroup> expected_enabled_groups; | |
137 expected_enabled_groups.insert(GROUP_PASSIVE); | |
138 EXPECT_EQ(expected_enabled_groups, session->GetEnabledGroups()); | |
139 } | |
140 | |
141 TEST_F(SyncSessionTest, EnabledGroups) { | |
142 scoped_ptr<SyncSession> session(MakeSession()); | |
143 std::set<ModelSafeGroup> expected_enabled_groups; | |
144 expected_enabled_groups.insert(GROUP_PASSIVE); | |
145 expected_enabled_groups.insert(GROUP_UI); | |
146 expected_enabled_groups.insert(GROUP_DB); | |
147 EXPECT_EQ(expected_enabled_groups, session->GetEnabledGroups()); | |
148 } | |
149 | |
150 TEST_F(SyncSessionTest, EnabledGroupsWithConflictsEmpty) { | |
151 scoped_ptr<SyncSession> session(MakeSession()); | |
152 // Auto-create conflict progress. This shouldn't put that group in | |
153 // conflict. | |
154 session->mutable_status_controller()-> | |
155 GetUnrestrictedMutableConflictProgressForTest(GROUP_PASSIVE); | |
156 EXPECT_TRUE(session->GetEnabledGroupsWithConflicts().empty()); | |
157 } | |
158 | |
159 TEST_F(SyncSessionTest, EnabledGroupsWithConflicts) { | |
160 scoped_ptr<SyncSession> session(MakeSession()); | |
161 // Put GROUP_UI in conflict. | |
162 session->mutable_status_controller()-> | |
163 GetUnrestrictedMutableConflictProgressForTest(GROUP_UI)-> | |
164 AddSimpleConflictingItemById(syncable::Id()); | |
165 std::set<ModelSafeGroup> expected_enabled_groups_with_conflicts; | |
166 expected_enabled_groups_with_conflicts.insert(GROUP_UI); | |
167 EXPECT_EQ(expected_enabled_groups_with_conflicts, | |
168 session->GetEnabledGroupsWithConflicts()); | |
169 } | |
170 | |
171 TEST_F(SyncSessionTest, ScopedContextHelpers) { | |
172 ConflictResolver resolver; | |
173 EXPECT_FALSE(context_->resolver()); | |
174 { | |
175 ScopedSessionContextConflictResolver s_resolver(context_.get(), &resolver); | |
176 EXPECT_EQ(&resolver, context_->resolver()); | |
177 } | |
178 EXPECT_FALSE(context_->resolver()); | |
179 } | |
180 | |
181 TEST_F(SyncSessionTest, SetWriteTransaction) { | |
182 TestDirectorySetterUpper dir_maker; | |
183 dir_maker.SetUp(); | |
184 syncable::Directory* directory = dir_maker.directory(); | |
185 | |
186 scoped_ptr<SyncSession> session(MakeSession()); | |
187 EXPECT_TRUE(NULL == session->write_transaction()); | |
188 { | |
189 WriteTransaction trans(FROM_HERE, syncable::UNITTEST, directory); | |
190 sessions::ScopedSetSessionWriteTransaction set_trans(session.get(), &trans); | |
191 EXPECT_TRUE(&trans == session->write_transaction()); | |
192 } | |
193 } | |
194 | |
195 TEST_F(SyncSessionTest, MoreToSyncIfUnsyncedGreaterThanCommitted) { | |
196 // If any forward progress was made during the session, and the number of | |
197 // unsynced handles still exceeds the number of commit ids we added, there is | |
198 // more to sync. For example, this occurs if we had more commit ids | |
199 // than could fit in a single commit batch. | |
200 EXPECT_FALSE(session_->HasMoreToSync()); | |
201 OrderedCommitSet commit_set(routes_); | |
202 commit_set.AddCommitItem(0, syncable::Id(), syncable::BOOKMARKS); | |
203 status()->set_commit_set(commit_set); | |
204 EXPECT_FALSE(session_->HasMoreToSync()); | |
205 | |
206 std::vector<int64> unsynced_handles; | |
207 unsynced_handles.push_back(1); | |
208 unsynced_handles.push_back(2); | |
209 status()->set_unsynced_handles(unsynced_handles); | |
210 EXPECT_FALSE(session_->HasMoreToSync()); | |
211 status()->increment_num_successful_commits(); | |
212 EXPECT_TRUE(session_->HasMoreToSync()); | |
213 } | |
214 | |
215 TEST_F(SyncSessionTest, MoreToDownloadIfDownloadFailed) { | |
216 status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); | |
217 | |
218 // When DownloadUpdatesCommand fails, these should be false. | |
219 EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); | |
220 EXPECT_FALSE(status()->download_updates_succeeded()); | |
221 | |
222 // Download updates has its own loop in the syncer; it shouldn't factor | |
223 // into HasMoreToSync. | |
224 EXPECT_FALSE(session_->HasMoreToSync()); | |
225 } | |
226 | |
227 TEST_F(SyncSessionTest, MoreToDownloadIfGotChangesRemaining) { | |
228 status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); | |
229 | |
230 // When the server returns changes_remaining, that means there's | |
231 // more to download. | |
232 status()->mutable_updates_response()->mutable_get_updates() | |
233 ->set_changes_remaining(1000L); | |
234 EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); | |
235 EXPECT_TRUE(status()->download_updates_succeeded()); | |
236 | |
237 // Download updates has its own loop in the syncer; it shouldn't factor | |
238 // into HasMoreToSync. | |
239 EXPECT_FALSE(session_->HasMoreToSync()); | |
240 } | |
241 | |
242 TEST_F(SyncSessionTest, MoreToDownloadIfGotNoChangesRemaining) { | |
243 status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); | |
244 | |
245 // When the server returns a timestamp, that means we're up to date. | |
246 status()->mutable_updates_response()->mutable_get_updates() | |
247 ->set_changes_remaining(0); | |
248 EXPECT_TRUE(status()->ServerSaysNothingMoreToDownload()); | |
249 EXPECT_TRUE(status()->download_updates_succeeded()); | |
250 | |
251 // Download updates has its own loop in the syncer; it shouldn't factor | |
252 // into HasMoreToSync. | |
253 EXPECT_FALSE(session_->HasMoreToSync()); | |
254 } | |
255 | |
256 TEST_F(SyncSessionTest, MoreToDownloadIfGotNoChangesRemainingForSubset) { | |
257 status()->set_updates_request_types(ParamsMeaningJustOneEnabledType()); | |
258 | |
259 // When the server returns a timestamp, that means we're up to date for that | |
260 // type. But there may still be more to download if there are other | |
261 // datatypes that we didn't request on this go-round. | |
262 status()->mutable_updates_response()->mutable_get_updates() | |
263 ->set_changes_remaining(0); | |
264 | |
265 EXPECT_TRUE(status()->ServerSaysNothingMoreToDownload()); | |
266 EXPECT_TRUE(status()->download_updates_succeeded()); | |
267 | |
268 // Download updates has its own loop in the syncer; it shouldn't factor | |
269 // into HasMoreToSync. | |
270 EXPECT_FALSE(session_->HasMoreToSync()); | |
271 } | |
272 | |
273 TEST_F(SyncSessionTest, MoreToDownloadIfGotChangesRemainingAndEntries) { | |
274 status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); | |
275 // The actual entry count should not factor into the HasMoreToSync | |
276 // determination. | |
277 status()->mutable_updates_response()->mutable_get_updates()->add_entries(); | |
278 status()->mutable_updates_response()->mutable_get_updates() | |
279 ->set_changes_remaining(1000000L);; | |
280 EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); | |
281 EXPECT_TRUE(status()->download_updates_succeeded()); | |
282 | |
283 // Download updates has its own loop in the syncer; it shouldn't factor | |
284 // into HasMoreToSync. | |
285 EXPECT_FALSE(session_->HasMoreToSync()); | |
286 } | |
287 | |
288 TEST_F(SyncSessionTest, MoreToDownloadIfGotNoChangesRemainingAndEntries) { | |
289 status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); | |
290 // The actual entry count should not factor into the HasMoreToSync | |
291 // determination. | |
292 status()->mutable_updates_response()->mutable_get_updates()->add_entries(); | |
293 status()->mutable_updates_response()->mutable_get_updates() | |
294 ->set_changes_remaining(0); | |
295 EXPECT_TRUE(status()->ServerSaysNothingMoreToDownload()); | |
296 EXPECT_TRUE(status()->download_updates_succeeded()); | |
297 | |
298 // Download updates has its own loop in the syncer; it shouldn't factor | |
299 // into HasMoreToSync. | |
300 EXPECT_FALSE(session_->HasMoreToSync()); | |
301 } | |
302 | |
303 TEST_F(SyncSessionTest, MoreToSyncIfConflictsResolved) { | |
304 // Conflict resolution happens after get updates and commit, | |
305 // so we need to loop back and get updates / commit again now | |
306 // that we have made forward progress. | |
307 status()->update_conflicts_resolved(true); | |
308 EXPECT_TRUE(session_->HasMoreToSync()); | |
309 } | |
310 | |
311 TEST_F(SyncSessionTest, ResetTransientState) { | |
312 status()->update_conflicts_resolved(true); | |
313 status()->increment_num_successful_commits(); | |
314 EXPECT_TRUE(session_->HasMoreToSync()); | |
315 session_->PrepareForAnotherSyncCycle(); | |
316 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION, | |
317 session_->source().updates_source); | |
318 EXPECT_FALSE(status()->conflicts_resolved()); | |
319 EXPECT_FALSE(session_->HasMoreToSync()); | |
320 EXPECT_FALSE(status()->TestAndClearIsDirty()); | |
321 } | |
322 | |
323 TEST_F(SyncSessionTest, Coalesce) { | |
324 std::vector<ModelSafeWorker*> workers_one, workers_two; | |
325 ModelSafeRoutingInfo routes_one, routes_two; | |
326 syncable::ModelTypePayloadMap one_type = | |
327 syncable::ModelTypePayloadMapFromEnumSet( | |
328 ParamsMeaningJustOneEnabledType(), | |
329 std::string()); | |
330 syncable::ModelTypePayloadMap all_types = | |
331 syncable::ModelTypePayloadMapFromEnumSet( | |
332 ParamsMeaningAllEnabledTypes(), | |
333 std::string()); | |
334 SyncSourceInfo source_one(sync_pb::GetUpdatesCallerInfo::PERIODIC, one_type); | |
335 SyncSourceInfo source_two(sync_pb::GetUpdatesCallerInfo::LOCAL, all_types); | |
336 | |
337 scoped_refptr<ModelSafeWorker> passive_worker( | |
338 new FakeModelWorker(GROUP_PASSIVE)); | |
339 scoped_refptr<ModelSafeWorker> db_worker(new FakeModelWorker(GROUP_DB)); | |
340 scoped_refptr<ModelSafeWorker> ui_worker(new FakeModelWorker(GROUP_UI)); | |
341 workers_one.push_back(passive_worker); | |
342 workers_one.push_back(db_worker); | |
343 workers_two.push_back(passive_worker); | |
344 workers_two.push_back(db_worker); | |
345 workers_two.push_back(ui_worker); | |
346 routes_one[syncable::AUTOFILL] = GROUP_DB; | |
347 routes_two[syncable::AUTOFILL] = GROUP_DB; | |
348 routes_two[syncable::BOOKMARKS] = GROUP_UI; | |
349 SyncSession one(context_.get(), this, source_one, routes_one, workers_one); | |
350 SyncSession two(context_.get(), this, source_two, routes_two, workers_two); | |
351 | |
352 std::set<ModelSafeGroup> expected_enabled_groups_one; | |
353 expected_enabled_groups_one.insert(GROUP_PASSIVE); | |
354 expected_enabled_groups_one.insert(GROUP_DB); | |
355 | |
356 std::set<ModelSafeGroup> expected_enabled_groups_two; | |
357 expected_enabled_groups_two.insert(GROUP_PASSIVE); | |
358 expected_enabled_groups_two.insert(GROUP_DB); | |
359 expected_enabled_groups_two.insert(GROUP_UI); | |
360 | |
361 EXPECT_EQ(expected_enabled_groups_one, one.GetEnabledGroups()); | |
362 EXPECT_EQ(expected_enabled_groups_two, two.GetEnabledGroups()); | |
363 | |
364 one.Coalesce(two); | |
365 | |
366 EXPECT_EQ(expected_enabled_groups_two, one.GetEnabledGroups()); | |
367 EXPECT_EQ(expected_enabled_groups_two, two.GetEnabledGroups()); | |
368 | |
369 EXPECT_EQ(two.source().updates_source, one.source().updates_source); | |
370 EXPECT_EQ(all_types, one.source().types); | |
371 std::vector<ModelSafeWorker*>::const_iterator it_db = | |
372 std::find(one.workers().begin(), one.workers().end(), db_worker); | |
373 std::vector<ModelSafeWorker*>::const_iterator it_ui = | |
374 std::find(one.workers().begin(), one.workers().end(), ui_worker); | |
375 EXPECT_NE(it_db, one.workers().end()); | |
376 EXPECT_NE(it_ui, one.workers().end()); | |
377 EXPECT_EQ(routes_two, one.routing_info()); | |
378 } | |
379 | |
380 TEST_F(SyncSessionTest, RebaseRoutingInfoWithLatestRemoveOneType) { | |
381 std::vector<ModelSafeWorker*> workers_one, workers_two; | |
382 ModelSafeRoutingInfo routes_one, routes_two; | |
383 syncable::ModelTypePayloadMap one_type = | |
384 syncable::ModelTypePayloadMapFromEnumSet( | |
385 ParamsMeaningJustOneEnabledType(), | |
386 std::string()); | |
387 syncable::ModelTypePayloadMap all_types = | |
388 syncable::ModelTypePayloadMapFromEnumSet( | |
389 ParamsMeaningAllEnabledTypes(), | |
390 std::string()); | |
391 SyncSourceInfo source_one(sync_pb::GetUpdatesCallerInfo::PERIODIC, one_type); | |
392 SyncSourceInfo source_two(sync_pb::GetUpdatesCallerInfo::LOCAL, all_types); | |
393 | |
394 scoped_refptr<ModelSafeWorker> passive_worker( | |
395 new FakeModelWorker(GROUP_PASSIVE)); | |
396 scoped_refptr<ModelSafeWorker> db_worker(new FakeModelWorker(GROUP_DB)); | |
397 scoped_refptr<ModelSafeWorker> ui_worker(new FakeModelWorker(GROUP_UI)); | |
398 workers_one.push_back(passive_worker); | |
399 workers_one.push_back(db_worker); | |
400 workers_two.push_back(passive_worker); | |
401 workers_two.push_back(db_worker); | |
402 workers_two.push_back(ui_worker); | |
403 routes_one[syncable::AUTOFILL] = GROUP_DB; | |
404 routes_two[syncable::AUTOFILL] = GROUP_DB; | |
405 routes_two[syncable::BOOKMARKS] = GROUP_UI; | |
406 SyncSession one(context_.get(), this, source_one, routes_one, workers_one); | |
407 SyncSession two(context_.get(), this, source_two, routes_two, workers_two); | |
408 | |
409 std::set<ModelSafeGroup> expected_enabled_groups_one; | |
410 expected_enabled_groups_one.insert(GROUP_PASSIVE); | |
411 expected_enabled_groups_one.insert(GROUP_DB); | |
412 | |
413 std::set<ModelSafeGroup> expected_enabled_groups_two; | |
414 expected_enabled_groups_two.insert(GROUP_PASSIVE); | |
415 expected_enabled_groups_two.insert(GROUP_DB); | |
416 expected_enabled_groups_two.insert(GROUP_UI); | |
417 | |
418 EXPECT_EQ(expected_enabled_groups_one, one.GetEnabledGroups()); | |
419 EXPECT_EQ(expected_enabled_groups_two, two.GetEnabledGroups()); | |
420 | |
421 two.RebaseRoutingInfoWithLatest(one); | |
422 | |
423 EXPECT_EQ(expected_enabled_groups_one, one.GetEnabledGroups()); | |
424 EXPECT_EQ(expected_enabled_groups_one, two.GetEnabledGroups()); | |
425 | |
426 // Make sure the source has not been touched. | |
427 EXPECT_EQ(two.source().updates_source, | |
428 sync_pb::GetUpdatesCallerInfo::LOCAL); | |
429 | |
430 // Make sure the payload is reduced to one. | |
431 EXPECT_EQ(one_type, two.source().types); | |
432 | |
433 // Make sure the workers are udpated. | |
434 std::vector<ModelSafeWorker*>::const_iterator it_db = | |
435 std::find(two.workers().begin(), two.workers().end(), db_worker); | |
436 std::vector<ModelSafeWorker*>::const_iterator it_ui = | |
437 std::find(two.workers().begin(), two.workers().end(), ui_worker); | |
438 EXPECT_NE(it_db, two.workers().end()); | |
439 EXPECT_EQ(it_ui, two.workers().end()); | |
440 EXPECT_EQ(two.workers().size(), 2U); | |
441 | |
442 // Make sure the model safe routing info is reduced to one type. | |
443 ModelSafeRoutingInfo::const_iterator it = | |
444 two.routing_info().find(syncable::AUTOFILL); | |
445 // Note that attempting to use EXPECT_NE would fail for an Android build due | |
446 // to seeming incompatibility with gtest and stlport. | |
447 EXPECT_TRUE(it != two.routing_info().end()); | |
448 EXPECT_EQ(it->second, GROUP_DB); | |
449 EXPECT_EQ(two.routing_info().size(), 1U); | |
450 } | |
451 | |
452 TEST_F(SyncSessionTest, RebaseRoutingInfoWithLatestWithSameType) { | |
453 std::vector<ModelSafeWorker*> workers_first, workers_second; | |
454 ModelSafeRoutingInfo routes_first, routes_second; | |
455 syncable::ModelTypePayloadMap all_types = | |
456 syncable::ModelTypePayloadMapFromEnumSet( | |
457 ParamsMeaningAllEnabledTypes(), | |
458 std::string()); | |
459 SyncSourceInfo source_first(sync_pb::GetUpdatesCallerInfo::PERIODIC, | |
460 all_types); | |
461 SyncSourceInfo source_second(sync_pb::GetUpdatesCallerInfo::LOCAL, | |
462 all_types); | |
463 | |
464 scoped_refptr<ModelSafeWorker> passive_worker( | |
465 new FakeModelWorker(GROUP_PASSIVE)); | |
466 scoped_refptr<FakeModelWorker> db_worker(new FakeModelWorker(GROUP_DB)); | |
467 scoped_refptr<FakeModelWorker> ui_worker(new FakeModelWorker(GROUP_UI)); | |
468 workers_first.push_back(passive_worker); | |
469 workers_first.push_back(db_worker); | |
470 workers_first.push_back(ui_worker); | |
471 workers_second.push_back(passive_worker); | |
472 workers_second.push_back(db_worker); | |
473 workers_second.push_back(ui_worker); | |
474 routes_first[syncable::AUTOFILL] = GROUP_DB; | |
475 routes_first[syncable::BOOKMARKS] = GROUP_UI; | |
476 routes_second[syncable::AUTOFILL] = GROUP_DB; | |
477 routes_second[syncable::BOOKMARKS] = GROUP_UI; | |
478 SyncSession first(context_.get(), this, source_first, routes_first, | |
479 workers_first); | |
480 SyncSession second(context_.get(), this, source_second, routes_second, | |
481 workers_second); | |
482 | |
483 std::set<ModelSafeGroup> expected_enabled_groups; | |
484 expected_enabled_groups.insert(GROUP_PASSIVE); | |
485 expected_enabled_groups.insert(GROUP_DB); | |
486 expected_enabled_groups.insert(GROUP_UI); | |
487 | |
488 EXPECT_EQ(expected_enabled_groups, first.GetEnabledGroups()); | |
489 EXPECT_EQ(expected_enabled_groups, second.GetEnabledGroups()); | |
490 | |
491 second.RebaseRoutingInfoWithLatest(first); | |
492 | |
493 EXPECT_EQ(expected_enabled_groups, first.GetEnabledGroups()); | |
494 EXPECT_EQ(expected_enabled_groups, second.GetEnabledGroups()); | |
495 | |
496 // Make sure the source has not been touched. | |
497 EXPECT_EQ(second.source().updates_source, | |
498 sync_pb::GetUpdatesCallerInfo::LOCAL); | |
499 | |
500 // Make sure our payload is still the same. | |
501 EXPECT_EQ(all_types, second.source().types); | |
502 | |
503 // Make sure the workers are still the same. | |
504 std::vector<ModelSafeWorker*>::const_iterator it_passive = | |
505 std::find(second.workers().begin(), second.workers().end(), | |
506 passive_worker); | |
507 std::vector<ModelSafeWorker*>::const_iterator it_db = | |
508 std::find(second.workers().begin(), second.workers().end(), db_worker); | |
509 std::vector<ModelSafeWorker*>::const_iterator it_ui = | |
510 std::find(second.workers().begin(), second.workers().end(), ui_worker); | |
511 EXPECT_NE(it_passive, second.workers().end()); | |
512 EXPECT_NE(it_db, second.workers().end()); | |
513 EXPECT_NE(it_ui, second.workers().end()); | |
514 EXPECT_EQ(second.workers().size(), 3U); | |
515 | |
516 // Make sure the model safe routing info is reduced to first type. | |
517 ModelSafeRoutingInfo::const_iterator it1 = | |
518 second.routing_info().find(syncable::AUTOFILL); | |
519 ModelSafeRoutingInfo::const_iterator it2 = | |
520 second.routing_info().find(syncable::BOOKMARKS); | |
521 | |
522 // Note that attempting to use EXPECT_NE would fail for an Android build due | |
523 // to seeming incompatibility with gtest and stlport. | |
524 EXPECT_TRUE(it1 != second.routing_info().end()); | |
525 EXPECT_EQ(it1->second, GROUP_DB); | |
526 | |
527 // Note that attempting to use EXPECT_NE would fail for an Android build due | |
528 // to seeming incompatibility with gtest and stlport. | |
529 EXPECT_TRUE(it2 != second.routing_info().end()); | |
530 EXPECT_EQ(it2->second, GROUP_UI); | |
531 EXPECT_EQ(second.routing_info().size(), 2U); | |
532 } | |
533 | |
534 | |
535 TEST_F(SyncSessionTest, MakeTypePayloadMapFromBitSet) { | |
536 syncable::ModelTypeSet types; | |
537 std::string payload = "test"; | |
538 syncable::ModelTypePayloadMap types_with_payloads = | |
539 syncable::ModelTypePayloadMapFromEnumSet(types, payload); | |
540 EXPECT_TRUE(types_with_payloads.empty()); | |
541 | |
542 types.Put(syncable::BOOKMARKS); | |
543 types.Put(syncable::PASSWORDS); | |
544 types.Put(syncable::AUTOFILL); | |
545 payload = "test2"; | |
546 types_with_payloads = | |
547 syncable::ModelTypePayloadMapFromEnumSet(types, payload); | |
548 | |
549 ASSERT_EQ(3U, types_with_payloads.size()); | |
550 EXPECT_EQ(types_with_payloads[syncable::BOOKMARKS], payload); | |
551 EXPECT_EQ(types_with_payloads[syncable::PASSWORDS], payload); | |
552 EXPECT_EQ(types_with_payloads[syncable::AUTOFILL], payload); | |
553 } | |
554 | |
555 TEST_F(SyncSessionTest, MakeTypePayloadMapFromRoutingInfo) { | |
556 std::string payload = "test"; | |
557 syncable::ModelTypePayloadMap types_with_payloads | |
558 = syncable::ModelTypePayloadMapFromRoutingInfo(routes_, payload); | |
559 ASSERT_EQ(routes_.size(), types_with_payloads.size()); | |
560 for (ModelSafeRoutingInfo::iterator iter = routes_.begin(); | |
561 iter != routes_.end(); | |
562 ++iter) { | |
563 EXPECT_EQ(payload, types_with_payloads[iter->first]); | |
564 } | |
565 } | |
566 | |
567 TEST_F(SyncSessionTest, CoalescePayloads) { | |
568 syncable::ModelTypePayloadMap original; | |
569 std::string empty_payload; | |
570 std::string payload1 = "payload1"; | |
571 std::string payload2 = "payload2"; | |
572 std::string payload3 = "payload3"; | |
573 original[syncable::BOOKMARKS] = empty_payload; | |
574 original[syncable::PASSWORDS] = payload1; | |
575 original[syncable::AUTOFILL] = payload2; | |
576 original[syncable::THEMES] = payload3; | |
577 | |
578 syncable::ModelTypePayloadMap update; | |
579 update[syncable::BOOKMARKS] = empty_payload; // Same. | |
580 update[syncable::PASSWORDS] = empty_payload; // Overwrite with empty. | |
581 update[syncable::AUTOFILL] = payload1; // Overwrite with non-empty. | |
582 update[syncable::SESSIONS] = payload2; // New. | |
583 // Themes untouched. | |
584 | |
585 CoalescePayloads(&original, update); | |
586 ASSERT_EQ(5U, original.size()); | |
587 EXPECT_EQ(empty_payload, original[syncable::BOOKMARKS]); | |
588 EXPECT_EQ(payload1, original[syncable::PASSWORDS]); | |
589 EXPECT_EQ(payload1, original[syncable::AUTOFILL]); | |
590 EXPECT_EQ(payload2, original[syncable::SESSIONS]); | |
591 EXPECT_EQ(payload3, original[syncable::THEMES]); | |
592 } | |
593 | |
594 } // namespace | |
595 } // namespace sessions | |
596 } // namespace browser_sync | |
OLD | NEW |