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.
5 #include "chrome/browser/sync/glue/sync_backend_host.h"
9 #include "base/location.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/test/test_timeouts.h"
14 #include "chrome/browser/prefs/pref_service_syncable.h"
15 #include "chrome/browser/sync/glue/device_info.h"
16 #include "chrome/browser/sync/glue/synced_device_tracker.h"
17 #include "chrome/browser/sync/invalidations/invalidator_storage.h"
18 #include "chrome/browser/sync/sync_prefs.h"
19 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "components/user_prefs/pref_registry_syncable.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/test/test_browser_thread.h"
24 #include "google/cacheinvalidation/include/types.h"
25 #include "googleurl/src/gurl.h"
26 #include "net/url_request/test_url_fetcher_factory.h"
27 #include "sync/internal_api/public/base/model_type.h"
28 #include "sync/internal_api/public/engine/model_safe_worker.h"
29 #include "sync/internal_api/public/sync_manager_factory.h"
30 #include "sync/internal_api/public/test/fake_sync_manager.h"
31 #include "sync/internal_api/public/util/experiments.h"
32 #include "sync/notifier/invalidator_state.h"
33 #include "sync/notifier/object_id_invalidation_map_test_util.h"
34 #include "sync/protocol/encryption.pb.h"
35 #include "sync/protocol/sync_protocol_error.h"
36 #include "sync/util/test_unrecoverable_error_handler.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "testing/gtest/include/gtest/gtest.h"
40 using content::BrowserThread
;
41 using syncer::FakeSyncManager
;
42 using syncer::SyncManager
;
43 using ::testing::InvokeWithoutArgs
;
44 using ::testing::StrictMock
;
47 namespace browser_sync
{
51 ACTION_P(Signal
, event
) {
55 void QuitMessageLoop() {
56 MessageLoop::current()->Quit();
59 class MockSyncFrontend
: public SyncFrontend
{
61 virtual ~MockSyncFrontend() {}
63 MOCK_METHOD1(OnInvalidatorStateChange
,
64 void(syncer::InvalidatorState
));
65 MOCK_METHOD1(OnIncomingInvalidation
,
66 void(const syncer::ObjectIdInvalidationMap
&));
69 void(const syncer::WeakHandle
<syncer::JsBackend
>&,
70 const syncer::WeakHandle
<syncer::DataTypeDebugInfoListener
>&,
72 MOCK_METHOD0(OnSyncCycleCompleted
, void());
73 MOCK_METHOD1(OnConnectionStatusChange
,
74 void(syncer::ConnectionStatus status
));
75 MOCK_METHOD0(OnStopSyncingPermanently
, void());
76 MOCK_METHOD0(OnClearServerDataSucceeded
, void());
77 MOCK_METHOD0(OnClearServerDataFailed
, void());
78 MOCK_METHOD2(OnPassphraseRequired
,
79 void(syncer::PassphraseRequiredReason
,
80 const sync_pb::EncryptedData
&));
81 MOCK_METHOD0(OnPassphraseAccepted
, void());
82 MOCK_METHOD2(OnEncryptedTypesChanged
,
83 void(syncer::ModelTypeSet
, bool));
84 MOCK_METHOD0(OnEncryptionComplete
, void());
85 MOCK_METHOD1(OnMigrationNeededForTypes
, void(syncer::ModelTypeSet
));
86 MOCK_METHOD1(OnExperimentsChanged
,
87 void(const syncer::Experiments
&));
88 MOCK_METHOD1(OnActionableError
,
89 void(const syncer::SyncProtocolError
& sync_error
));
90 MOCK_METHOD0(OnSyncConfigureRetry
, void());
93 class FakeSyncManagerFactory
: public syncer::SyncManagerFactory
{
95 FakeSyncManagerFactory() : fake_manager_(NULL
) {}
96 virtual ~FakeSyncManagerFactory() {}
98 // SyncManagerFactory implementation. Called on the sync thread.
99 virtual scoped_ptr
<SyncManager
> CreateSyncManager(
100 std::string name
) OVERRIDE
{
101 DCHECK(!fake_manager_
);
102 fake_manager_
= new FakeSyncManager(initial_sync_ended_types_
,
103 progress_marker_types_
,
104 configure_fail_types_
);
105 return scoped_ptr
<SyncManager
>(fake_manager_
);
108 // Returns NULL until CreateSyncManager() is called on the sync
109 // thread. Called on the main thread, but only after
110 // OnBackendInitialized() is called (which is strictly after
111 // CreateSyncManager is called on the sync thread).
112 FakeSyncManager
* fake_manager() {
113 return fake_manager_
;
116 void set_initial_sync_ended_types(syncer::ModelTypeSet types
) {
117 initial_sync_ended_types_
= types
;
120 void set_progress_marker_types(syncer::ModelTypeSet types
) {
121 progress_marker_types_
= types
;
124 void set_configure_fail_types(syncer::ModelTypeSet types
) {
125 configure_fail_types_
= types
;
129 syncer::ModelTypeSet initial_sync_ended_types_
;
130 syncer::ModelTypeSet progress_marker_types_
;
131 syncer::ModelTypeSet configure_fail_types_
;
132 FakeSyncManager
* fake_manager_
;
135 class SyncBackendHostTest
: public testing::Test
{
137 SyncBackendHostTest()
138 : ui_thread_(BrowserThread::UI
, &ui_loop_
),
139 io_thread_(BrowserThread::IO
),
140 fake_manager_(NULL
) {}
142 virtual ~SyncBackendHostTest() {}
144 virtual void SetUp() OVERRIDE
{
145 io_thread_
.StartIOThread();
146 profile_
.reset(new TestingProfile());
147 profile_
->CreateRequestContext();
148 sync_prefs_
.reset(new SyncPrefs(profile_
->GetPrefs()));
149 invalidator_storage_
.reset(new InvalidatorStorage(
150 profile_
->GetPrefs()));
151 backend_
.reset(new SyncBackendHost(
152 profile_
->GetDebugName(),
154 sync_prefs_
->AsWeakPtr(),
155 invalidator_storage_
->AsWeakPtr()));
156 credentials_
.email
= "user@example.com";
157 credentials_
.sync_token
= "sync_token";
159 // These types are always implicitly enabled.
160 enabled_types_
.PutAll(syncer::ControlTypes());
162 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
163 // Registrar removing them if it can't find their model workers.
164 enabled_types_
.Put(syncer::BOOKMARKS
);
165 enabled_types_
.Put(syncer::NIGORI
);
166 enabled_types_
.Put(syncer::DEVICE_INFO
);
167 enabled_types_
.Put(syncer::PREFERENCES
);
168 enabled_types_
.Put(syncer::SESSIONS
);
169 enabled_types_
.Put(syncer::SEARCH_ENGINES
);
170 enabled_types_
.Put(syncer::AUTOFILL
);
171 enabled_types_
.Put(syncer::EXPERIMENTS
);
174 virtual void TearDown() OVERRIDE
{
175 if (backend_
.get()) {
176 backend_
->StopSyncingForShutdown();
177 backend_
->Shutdown(false);
181 invalidator_storage_
.reset();
183 // Pump messages posted by the sync thread (which may end up
184 // posting on the IO thread).
185 ui_loop_
.RunUntilIdle();
187 // Pump any messages posted by the IO thread.
188 ui_loop_
.RunUntilIdle();
191 // Synchronously initializes the backend.
192 void InitializeBackend(bool expect_success
) {
193 EXPECT_CALL(mock_frontend_
, OnBackendInitialized(_
, _
, expect_success
)).
194 WillOnce(InvokeWithoutArgs(QuitMessageLoop
));
195 backend_
->Initialize(&mock_frontend_
,
196 syncer::WeakHandle
<syncer::JsEventHandler
>(),
200 &fake_manager_factory_
,
203 ui_loop_
.PostDelayedTask(FROM_HERE
,
204 ui_loop_
.QuitClosure(), TestTimeouts::action_timeout());
206 // |fake_manager_factory_|'s fake_manager() is set on the sync
207 // thread, but we can rely on the message loop barriers to
208 // guarantee that we see the updated value.
209 fake_manager_
= fake_manager_factory_
.fake_manager();
210 DCHECK(fake_manager_
);
213 // Synchronously configures the backend's datatypes.
214 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add
,
215 syncer::ModelTypeSet types_to_remove
) {
216 BackendDataTypeConfigurer::DataTypeConfigStateMap config_state_map
;
217 BackendDataTypeConfigurer::SetDataTypesState(
218 BackendDataTypeConfigurer::ENABLED
, types_to_add
, &config_state_map
);
219 BackendDataTypeConfigurer::SetDataTypesState(
220 BackendDataTypeConfigurer::DISABLED
,
221 types_to_remove
, &config_state_map
);
223 types_to_add
.PutAll(syncer::ControlTypes());
224 backend_
->ConfigureDataTypes(
225 syncer::CONFIGURE_REASON_RECONFIGURATION
,
227 base::Bind(&SyncBackendHostTest::DownloadReady
,
228 base::Unretained(this)),
229 base::Bind(&SyncBackendHostTest::OnDownloadRetry
,
230 base::Unretained(this)));
231 ui_loop_
.PostDelayedTask(FROM_HERE
,
232 ui_loop_
.QuitClosure(), TestTimeouts::action_timeout());
236 void IssueRefreshRequest(syncer::ModelTypeSet types
) {
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
239 syncer::ModelTypeInvalidationMap
invalidation_map(
240 ModelTypeSetToInvalidationMap(types
, std::string()));
242 content::NotificationService::current()->Notify(
243 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL
,
244 content::Source
<Profile
>(profile_
.get()),
245 content::Details
<syncer::ModelTypeInvalidationMap
>(
250 void DownloadReady(syncer::ModelTypeSet types
) {
251 MessageLoop::current()->Quit();
254 void OnDownloadRetry() {
258 MessageLoop ui_loop_
;
259 content::TestBrowserThread ui_thread_
;
260 content::TestBrowserThread io_thread_
;
261 StrictMock
<MockSyncFrontend
> mock_frontend_
;
262 syncer::SyncCredentials credentials_
;
263 syncer::TestUnrecoverableErrorHandler handler_
;
264 scoped_ptr
<TestingProfile
> profile_
;
265 scoped_ptr
<SyncPrefs
> sync_prefs_
;
266 scoped_ptr
<InvalidatorStorage
> invalidator_storage_
;
267 scoped_ptr
<SyncBackendHost
> backend_
;
268 FakeSyncManager
* fake_manager_
;
269 FakeSyncManagerFactory fake_manager_factory_
;
270 syncer::ModelTypeSet enabled_types_
;
273 // Test basic initialization with no initial types (first time initialization).
274 // Only the nigori should be configured.
275 TEST_F(SyncBackendHostTest
, InitShutdown
) {
276 InitializeBackend(true);
277 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
278 syncer::ControlTypes()));
279 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
280 syncer::ControlTypes()));
281 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
282 syncer::ControlTypes()).Empty());
285 // Test first time sync scenario. All types should be properly configured.
286 TEST_F(SyncBackendHostTest
, FirstTimeSync
) {
287 InitializeBackend(true);
288 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
289 syncer::ControlTypes()));
290 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
291 syncer::ControlTypes()));
292 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
293 syncer::ControlTypes()).Empty());
295 ConfigureDataTypes(enabled_types_
,
296 Difference(syncer::ModelTypeSet::All(),
298 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
299 Difference(enabled_types_
, syncer::ControlTypes())));
300 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
301 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
302 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
303 enabled_types_
).Empty());
306 // Test the restart after setting up sync scenario. No enabled types should be
307 // downloaded or cleaned.
308 TEST_F(SyncBackendHostTest
, Restart
) {
309 sync_prefs_
->SetSyncSetupCompleted();
310 syncer::ModelTypeSet all_but_nigori
= enabled_types_
;
311 fake_manager_factory_
.set_progress_marker_types(enabled_types_
);
312 fake_manager_factory_
.set_initial_sync_ended_types(enabled_types_
);
313 InitializeBackend(true);
314 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
315 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
316 enabled_types_
).Empty());
317 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
318 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
319 enabled_types_
).Empty());
321 ConfigureDataTypes(enabled_types_
,
322 Difference(syncer::ModelTypeSet::All(),
324 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
325 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
326 enabled_types_
).Empty());
327 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
328 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
329 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
330 enabled_types_
).Empty());
333 // Test a sync restart scenario where some types had never finished configuring.
334 // The partial types should be purged, then reconfigured properly.
335 TEST_F(SyncBackendHostTest
, PartialTypes
) {
336 sync_prefs_
->SetSyncSetupCompleted();
337 // Set sync manager behavior before passing it down. All types have progress
338 // markers, but nigori and bookmarks are missing initial sync ended.
339 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
340 syncer::ModelTypeSet full_types
=
341 Difference(enabled_types_
, partial_types
);
342 fake_manager_factory_
.set_progress_marker_types(enabled_types_
);
343 fake_manager_factory_
.set_initial_sync_ended_types(full_types
);
345 // Bringing up the backend should purge all partial types, then proceed to
346 // download the Nigori.
347 InitializeBackend(true);
348 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
349 syncer::ModelTypeSet(syncer::NIGORI
)));
350 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
351 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
352 Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
353 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
354 enabled_types_
).Equals(
355 Difference(partial_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
357 // Now do the actual configuration, which should download and apply bookmarks.
358 ConfigureDataTypes(enabled_types_
,
359 Difference(syncer::ModelTypeSet::All(),
361 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
362 enabled_types_
).Empty());
363 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
365 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
366 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
367 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
368 enabled_types_
).Empty());
371 // Test the behavior when we lose the sync db. Although we already have types
372 // enabled, we should re-download all of them because we lost their data.
373 TEST_F(SyncBackendHostTest
, LostDB
) {
374 sync_prefs_
->SetSyncSetupCompleted();
375 // Initialization should fetch the Nigori node. Everything else should be
377 InitializeBackend(true);
378 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
379 syncer::ModelTypeSet(syncer::ControlTypes())));
380 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
381 syncer::ModelTypeSet(syncer::ControlTypes())));
382 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
383 enabled_types_
).Equals(
384 Difference(enabled_types_
, syncer::ControlTypes())));
386 // The database was empty, so any cleaning is entirely optional. We want to
387 // reset this value before running the next part of the test, though.
388 fake_manager_
->GetAndResetCleanedTypes();
390 // The actual configuration should redownload and apply all the enabled types.
391 ConfigureDataTypes(enabled_types_
,
392 Difference(syncer::ModelTypeSet::All(),
394 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
395 Difference(enabled_types_
, syncer::ControlTypes())));
396 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
397 enabled_types_
).Empty());
398 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
399 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
400 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
401 enabled_types_
).Empty());
404 TEST_F(SyncBackendHostTest
, DisableTypes
) {
405 // Simulate first time sync.
406 InitializeBackend(true);
407 fake_manager_
->GetAndResetCleanedTypes();
408 ConfigureDataTypes(enabled_types_
,
409 Difference(syncer::ModelTypeSet::All(),
411 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
413 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
414 enabled_types_
).Empty());
415 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
416 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
417 enabled_types_
).Empty());
419 // Then disable two datatypes.
420 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
421 syncer::SEARCH_ENGINES
);
422 syncer::ModelTypeSet old_types
= enabled_types_
;
423 enabled_types_
.RemoveAll(disabled_types
);
424 ConfigureDataTypes(enabled_types_
,
425 Difference(syncer::ModelTypeSet::All(),
428 // Only those datatypes disabled should be cleaned. Nothing should be
430 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
431 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
432 old_types
).Equals(disabled_types
));
433 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
434 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
435 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
436 enabled_types_
).Empty());
439 TEST_F(SyncBackendHostTest
, AddTypes
) {
440 // Simulate first time sync.
441 InitializeBackend(true);
442 fake_manager_
->GetAndResetCleanedTypes();
443 ConfigureDataTypes(enabled_types_
,
444 Difference(syncer::ModelTypeSet::All(),
446 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
448 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
449 enabled_types_
).Empty());
450 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
451 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
452 enabled_types_
).Empty());
454 // Then add two datatypes.
455 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
457 enabled_types_
.PutAll(new_types
);
458 ConfigureDataTypes(enabled_types_
,
459 Difference(syncer::ModelTypeSet::All(),
462 // Only those datatypes added should be downloaded (plus nigori). Nothing
463 // should be cleaned aside from the disabled types.
464 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
465 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
466 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
467 enabled_types_
).Empty());
468 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
469 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
470 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
471 enabled_types_
).Empty());
474 // And and disable in the same configuration.
475 TEST_F(SyncBackendHostTest
, AddDisableTypes
) {
476 // Simulate first time sync.
477 InitializeBackend(true);
478 fake_manager_
->GetAndResetCleanedTypes();
479 ConfigureDataTypes(enabled_types_
,
480 Difference(syncer::ModelTypeSet::All(),
482 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
484 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
485 enabled_types_
).Empty());
486 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
487 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
488 enabled_types_
).Empty());
490 // Then add two datatypes.
491 syncer::ModelTypeSet old_types
= enabled_types_
;
492 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
493 syncer::SEARCH_ENGINES
);
494 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
496 enabled_types_
.PutAll(new_types
);
497 enabled_types_
.RemoveAll(disabled_types
);
498 ConfigureDataTypes(enabled_types_
,
499 Difference(syncer::ModelTypeSet::All(),
502 // Only those datatypes added should be downloaded (plus nigori). Nothing
503 // should be cleaned aside from the disabled types.
504 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
505 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
506 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
507 old_types
).Equals(disabled_types
));
508 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
509 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
510 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
511 old_types
).Equals(disabled_types
));
514 // Test restarting the browser to newly supported datatypes. The new datatypes
515 // should be downloaded on the configuration after backend initialization.
516 TEST_F(SyncBackendHostTest
, NewlySupportedTypes
) {
517 sync_prefs_
->SetSyncSetupCompleted();
518 // Set sync manager behavior before passing it down. All types have progress
519 // markers and initial sync ended except the new types.
520 syncer::ModelTypeSet old_types
= enabled_types_
;
521 fake_manager_factory_
.set_progress_marker_types(old_types
);
522 fake_manager_factory_
.set_initial_sync_ended_types(old_types
);
523 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
524 syncer::EXTENSION_SETTINGS
);
525 enabled_types_
.PutAll(new_types
);
528 InitializeBackend(true);
529 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
530 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
532 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(old_types
));
533 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
534 enabled_types_
).Equals(new_types
));
536 // Downloads and applies the new types.
537 ConfigureDataTypes(enabled_types_
,
538 Difference(syncer::ModelTypeSet::All(),
540 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
541 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
542 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
543 enabled_types_
).Empty());
544 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
545 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
546 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
547 enabled_types_
).Empty());
550 // Test the newly supported types scenario, but with the presence of partial
551 // types as well. Both partial and newly supported types should be downloaded
552 // the configuration.
553 TEST_F(SyncBackendHostTest
, NewlySupportedTypesWithPartialTypes
) {
554 sync_prefs_
->SetSyncSetupCompleted();
555 // Set sync manager behavior before passing it down. All types have progress
556 // markers and initial sync ended except the new types.
557 syncer::ModelTypeSet old_types
= enabled_types_
;
558 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
559 syncer::ModelTypeSet full_types
=
560 Difference(enabled_types_
, partial_types
);
561 fake_manager_factory_
.set_progress_marker_types(old_types
);
562 fake_manager_factory_
.set_initial_sync_ended_types(full_types
);
563 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
564 syncer::EXTENSION_SETTINGS
);
565 enabled_types_
.PutAll(new_types
);
567 // Purge the partial types. The nigori will be among the purged types, but
568 // the syncer will re-download it by the time the initialization is complete.
569 InitializeBackend(true);
570 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
571 syncer::ModelTypeSet(syncer::NIGORI
)));
572 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
573 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
574 syncer::Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
575 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
576 enabled_types_
).Equals(Union(new_types
, Difference(
577 partial_types
, syncer::ModelTypeSet(syncer::NIGORI
)))));
579 // Downloads and applies the new types and partial types (which includes
581 ConfigureDataTypes(enabled_types_
,
582 Difference(syncer::ModelTypeSet::All(),
584 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
585 Union(new_types
, partial_types
)));
586 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
587 enabled_types_
).Empty());
588 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
589 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
590 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
591 enabled_types_
).Empty());
594 // Register for some IDs and trigger an invalidation. This should
595 // propagate all the way to the frontend.
596 TEST_F(SyncBackendHostTest
, Invalidate
) {
597 InitializeBackend(true);
599 syncer::ObjectIdSet ids
;
600 ids
.insert(invalidation::ObjectId(1, "id1"));
601 ids
.insert(invalidation::ObjectId(2, "id2"));
602 const syncer::ObjectIdInvalidationMap
& invalidation_map
=
603 syncer::ObjectIdSetToInvalidationMap(ids
, "payload");
607 OnIncomingInvalidation(invalidation_map
))
608 .WillOnce(InvokeWithoutArgs(QuitMessageLoop
));
610 backend_
->UpdateRegisteredInvalidationIds(ids
);
611 fake_manager_
->Invalidate(invalidation_map
);
612 ui_loop_
.PostDelayedTask(
613 FROM_HERE
, ui_loop_
.QuitClosure(), TestTimeouts::action_timeout());
617 // Register for some IDs and update the invalidator state. This
618 // should propagate all the way to the frontend.
619 TEST_F(SyncBackendHostTest
, UpdateInvalidatorState
) {
620 InitializeBackend(true);
622 EXPECT_CALL(mock_frontend_
,
623 OnInvalidatorStateChange(syncer::INVALIDATIONS_ENABLED
))
624 .WillOnce(InvokeWithoutArgs(QuitMessageLoop
));
626 syncer::ObjectIdSet ids
;
627 ids
.insert(invalidation::ObjectId(3, "id3"));
628 backend_
->UpdateRegisteredInvalidationIds(ids
);
629 fake_manager_
->UpdateInvalidatorState(syncer::INVALIDATIONS_ENABLED
);
630 ui_loop_
.PostDelayedTask(
631 FROM_HERE
, ui_loop_
.QuitClosure(), TestTimeouts::action_timeout());
635 // Call StopSyncingForShutdown() on the backend and fire some invalidations
636 // before calling Shutdown(). Then start up and shut down the backend again.
637 // Those notifications shouldn't propagate to the frontend.
638 TEST_F(SyncBackendHostTest
, InvalidationsAfterStopSyncingForShutdown
) {
639 InitializeBackend(true);
641 syncer::ObjectIdSet ids
;
642 ids
.insert(invalidation::ObjectId(5, "id5"));
643 backend_
->UpdateRegisteredInvalidationIds(ids
);
645 backend_
->StopSyncingForShutdown();
647 // Should not trigger anything.
648 fake_manager_
->UpdateInvalidatorState(syncer::TRANSIENT_INVALIDATION_ERROR
);
649 fake_manager_
->UpdateInvalidatorState(syncer::INVALIDATIONS_ENABLED
);
650 const syncer::ObjectIdInvalidationMap
& invalidation_map
=
651 syncer::ObjectIdSetToInvalidationMap(ids
, "payload");
652 fake_manager_
->Invalidate(invalidation_map
);
654 // Make sure the above calls take effect before we continue.
655 fake_manager_
->WaitForSyncThread();
657 backend_
->Shutdown(false);
664 // Ensure the device info tracker is initialized properly on startup.
665 TEST_F(SyncBackendHostTest
, InitializeDeviceInfo
) {
666 ASSERT_EQ(NULL
, backend_
->GetSyncedDeviceTracker());
668 InitializeBackend(true);
669 const SyncedDeviceTracker
* device_tracker
=
670 backend_
->GetSyncedDeviceTracker();
671 ASSERT_TRUE(device_tracker
->ReadLocalDeviceInfo());
674 // Verify that downloading control types only downloads those types that do
675 // not have initial sync ended set.
676 TEST_F(SyncBackendHostTest
, DownloadControlTypes
) {
677 sync_prefs_
->SetSyncSetupCompleted();
678 // Set sync manager behavior before passing it down. Experiments and device
679 // info are new types without progress markers or initial sync ended, while
680 // all other types have been fully downloaded and applied.
681 syncer::ModelTypeSet
new_types(syncer::EXPERIMENTS
, syncer::DEVICE_INFO
);
682 syncer::ModelTypeSet old_types
=
683 Difference(enabled_types_
, new_types
);
684 fake_manager_factory_
.set_progress_marker_types(old_types
);
685 fake_manager_factory_
.set_initial_sync_ended_types(old_types
);
687 // Bringing up the backend should download the new types without downloading
689 InitializeBackend(true);
690 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(new_types
));
691 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
692 enabled_types_
).Empty());
693 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
694 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
695 enabled_types_
).Empty());
698 // Fail to download control types. It's believed that there is a server bug
699 // which can allow this to happen (crbug.com/164288). The sync backend host
700 // should detect this condition and fail to initialize the backend.
702 // The failure is "silent" in the sense that the GetUpdates request appears to
703 // be successful, but it returned no results. This means that the usual
704 // download retry logic will not be invoked.
705 TEST_F(SyncBackendHostTest
, SilentlyFailToDownloadControlTypes
) {
706 fake_manager_factory_
.set_configure_fail_types(syncer::ModelTypeSet::All());
707 InitializeBackend(false);
710 // Test that local refresh requests are delivered to sync.
711 TEST_F(SyncBackendHostTest
, ForwardLocalRefreshRequest
) {
712 InitializeBackend(true);
714 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
715 IssueRefreshRequest(set1
);
716 fake_manager_
->WaitForSyncThread();
717 EXPECT_TRUE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
719 syncer::ModelTypeSet set2
= syncer::ModelTypeSet(syncer::SESSIONS
);
720 IssueRefreshRequest(set2
);
721 fake_manager_
->WaitForSyncThread();
722 EXPECT_TRUE(set2
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
725 // Test that local invalidations issued before sync is initialized are ignored.
726 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestEarly
) {
727 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
728 IssueRefreshRequest(set1
);
730 InitializeBackend(true);
732 fake_manager_
->WaitForSyncThread();
733 EXPECT_FALSE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
736 // Test that local invalidations issued while sync is shutting down are ignored.
737 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestLate
) {
738 InitializeBackend(true);
740 backend_
->StopSyncingForShutdown();
742 syncer::ModelTypeSet types
= syncer::ModelTypeSet::All();
743 IssueRefreshRequest(types
);
744 fake_manager_
->WaitForSyncThread();
745 EXPECT_FALSE(types
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
747 backend_
->Shutdown(false);
753 } // namespace browser_sync