1 // Copyright 2013 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_impl.h"
9 #include "base/files/file_util.h"
10 #include "base/location.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/test/test_timeouts.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
17 #include "chrome/browser/prefs/pref_service_syncable.h"
18 #include "chrome/test/base/testing_browser_process.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "chrome/test/base/testing_profile_manager.h"
21 #include "components/invalidation/impl/invalidator_storage.h"
22 #include "components/invalidation/impl/profile_invalidation_provider.h"
23 #include "components/invalidation/public/invalidator_state.h"
24 #include "components/invalidation/public/object_id_invalidation_map.h"
25 #include "components/sync_driver/device_info.h"
26 #include "components/sync_driver/sync_frontend.h"
27 #include "components/sync_driver/sync_prefs.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/test/test_browser_thread_bundle.h"
30 #include "content/public/test/test_utils.h"
31 #include "google/cacheinvalidation/include/types.h"
32 #include "google_apis/gaia/gaia_constants.h"
33 #include "net/url_request/test_url_fetcher_factory.h"
34 #include "sync/internal_api/public/base/model_type.h"
35 #include "sync/internal_api/public/engine/model_safe_worker.h"
36 #include "sync/internal_api/public/http_bridge_network_resources.h"
37 #include "sync/internal_api/public/network_resources.h"
38 #include "sync/internal_api/public/sessions/commit_counters.h"
39 #include "sync/internal_api/public/sessions/status_counters.h"
40 #include "sync/internal_api/public/sessions/update_counters.h"
41 #include "sync/internal_api/public/sync_manager_factory.h"
42 #include "sync/internal_api/public/test/fake_sync_manager.h"
43 #include "sync/internal_api/public/util/experiments.h"
44 #include "sync/protocol/encryption.pb.h"
45 #include "sync/protocol/sync_protocol_error.h"
46 #include "sync/test/callback_counter.h"
47 #include "sync/util/test_unrecoverable_error_handler.h"
48 #include "testing/gmock/include/gmock/gmock.h"
49 #include "testing/gtest/include/gtest/gtest.h"
52 using content::BrowserThread
;
53 using syncer::FakeSyncManager
;
54 using syncer::SyncManager
;
55 using ::testing::InvokeWithoutArgs
;
56 using ::testing::StrictMock
;
59 namespace browser_sync
{
63 const char kTestProfileName
[] = "test-profile";
65 static const base::FilePath::CharType kTestSyncDir
[] =
66 FILE_PATH_LITERAL("sync-test");
68 ACTION_P(Signal
, event
) {
72 void QuitMessageLoop() {
73 base::MessageLoop::current()->Quit();
76 class MockSyncFrontend
: public sync_driver::SyncFrontend
{
78 virtual ~MockSyncFrontend() {}
82 void(const syncer::WeakHandle
<syncer::JsBackend
>&,
83 const syncer::WeakHandle
<syncer::DataTypeDebugInfoListener
>&,
86 MOCK_METHOD0(OnSyncCycleCompleted
, void());
87 MOCK_METHOD1(OnConnectionStatusChange
,
88 void(syncer::ConnectionStatus status
));
89 MOCK_METHOD0(OnClearServerDataSucceeded
, void());
90 MOCK_METHOD0(OnClearServerDataFailed
, void());
91 MOCK_METHOD2(OnPassphraseRequired
,
92 void(syncer::PassphraseRequiredReason
,
93 const sync_pb::EncryptedData
&));
94 MOCK_METHOD0(OnPassphraseAccepted
, void());
95 MOCK_METHOD2(OnEncryptedTypesChanged
,
96 void(syncer::ModelTypeSet
, bool));
97 MOCK_METHOD0(OnEncryptionComplete
, void());
98 MOCK_METHOD1(OnMigrationNeededForTypes
, void(syncer::ModelTypeSet
));
99 MOCK_METHOD1(OnProtocolEvent
, void(const syncer::ProtocolEvent
&));
100 MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated
,
101 void(syncer::ModelType
, const syncer::CommitCounters
&));
102 MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated
,
103 void(syncer::ModelType
, const syncer::UpdateCounters
&));
104 MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated
,
105 void(syncer::ModelType
, const syncer::StatusCounters
&));
106 MOCK_METHOD1(OnExperimentsChanged
,
107 void(const syncer::Experiments
&));
108 MOCK_METHOD1(OnActionableError
,
109 void(const syncer::SyncProtocolError
& sync_error
));
110 MOCK_METHOD0(OnSyncConfigureRetry
, void());
112 OnLocalSetPassphraseEncryption
,
113 void(const syncer::SyncEncryptionHandler::NigoriState
& nigori_state
));
116 class FakeSyncManagerFactory
: public syncer::SyncManagerFactory
{
118 explicit FakeSyncManagerFactory(FakeSyncManager
** fake_manager
)
119 : SyncManagerFactory(NORMAL
),
120 fake_manager_(fake_manager
) {
121 *fake_manager_
= NULL
;
123 ~FakeSyncManagerFactory() override
{}
125 // SyncManagerFactory implementation. Called on the sync thread.
126 scoped_ptr
<SyncManager
> CreateSyncManager(std::string name
) override
{
127 *fake_manager_
= new FakeSyncManager(initial_sync_ended_types_
,
128 progress_marker_types_
,
129 configure_fail_types_
);
130 return scoped_ptr
<SyncManager
>(*fake_manager_
);
133 void set_initial_sync_ended_types(syncer::ModelTypeSet types
) {
134 initial_sync_ended_types_
= types
;
137 void set_progress_marker_types(syncer::ModelTypeSet types
) {
138 progress_marker_types_
= types
;
141 void set_configure_fail_types(syncer::ModelTypeSet types
) {
142 configure_fail_types_
= types
;
146 syncer::ModelTypeSet initial_sync_ended_types_
;
147 syncer::ModelTypeSet progress_marker_types_
;
148 syncer::ModelTypeSet configure_fail_types_
;
149 FakeSyncManager
** fake_manager_
;
152 class SyncBackendHostTest
: public testing::Test
{
154 SyncBackendHostTest()
155 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD
),
156 profile_manager_(TestingBrowserProcess::GetGlobal()),
157 fake_manager_(NULL
) {}
159 ~SyncBackendHostTest() override
{}
161 void SetUp() override
{
162 ASSERT_TRUE(profile_manager_
.SetUp());
163 profile_
= profile_manager_
.CreateTestingProfile(kTestProfileName
);
164 sync_prefs_
.reset(new sync_driver::SyncPrefs(profile_
->GetPrefs()));
165 backend_
.reset(new SyncBackendHostImpl(
166 profile_
->GetDebugName(),
168 invalidation::ProfileInvalidationProviderFactory::GetForProfile(
169 profile_
)->GetInvalidationService(),
170 sync_prefs_
->AsWeakPtr(),
171 base::FilePath(kTestSyncDir
)));
172 credentials_
.email
= "user@example.com";
173 credentials_
.sync_token
= "sync_token";
174 credentials_
.scope_set
.insert(GaiaConstants::kChromeSyncOAuth2Scope
);
176 fake_manager_factory_
.reset(new FakeSyncManagerFactory(&fake_manager_
));
178 // These types are always implicitly enabled.
179 enabled_types_
.PutAll(syncer::ControlTypes());
181 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
182 // Registrar removing them if it can't find their model workers.
183 enabled_types_
.Put(syncer::BOOKMARKS
);
184 enabled_types_
.Put(syncer::PREFERENCES
);
185 enabled_types_
.Put(syncer::SESSIONS
);
186 enabled_types_
.Put(syncer::SEARCH_ENGINES
);
187 enabled_types_
.Put(syncer::AUTOFILL
);
189 network_resources_
.reset(new syncer::HttpBridgeNetworkResources());
192 void TearDown() override
{
194 backend_
->StopSyncingForShutdown();
195 backend_
->Shutdown(syncer::STOP_SYNC
);
200 profile_manager_
.DeleteTestingProfile(kTestProfileName
);
201 // Pump messages posted by the sync thread (which may end up
202 // posting on the IO thread).
203 base::RunLoop().RunUntilIdle();
204 content::RunAllPendingInMessageLoop(BrowserThread::IO
);
205 // Pump any messages posted by the IO thread.
206 base::RunLoop().RunUntilIdle();
209 // Synchronously initializes the backend.
210 void InitializeBackend(bool expect_success
) {
211 EXPECT_CALL(mock_frontend_
, OnBackendInitialized(_
, _
, _
, expect_success
)).
212 WillOnce(InvokeWithoutArgs(QuitMessageLoop
));
213 backend_
->Initialize(
215 scoped_ptr
<base::Thread
>(),
216 syncer::WeakHandle
<syncer::JsEventHandler
>(),
221 fake_manager_factory_
.Pass(),
222 MakeWeakHandle(test_unrecoverable_error_handler_
.GetWeakPtr()),
224 network_resources_
.get(),
225 saved_nigori_state_
.Pass());
226 base::RunLoop run_loop
;
227 BrowserThread::PostDelayedTask(BrowserThread::UI
, FROM_HERE
,
228 run_loop
.QuitClosure(),
229 TestTimeouts::action_timeout());
231 // |fake_manager_factory_|'s fake_manager() is set on the sync
232 // thread, but we can rely on the message loop barriers to
233 // guarantee that we see the updated value.
234 DCHECK(fake_manager_
);
237 // Synchronously configures the backend's datatypes.
238 syncer::ModelTypeSet
ConfigureDataTypes(
239 syncer::ModelTypeSet types_to_add
,
240 syncer::ModelTypeSet types_to_remove
,
241 syncer::ModelTypeSet types_to_unapply
) {
242 sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap
244 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
245 sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE
,
248 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
249 sync_driver::BackendDataTypeConfigurer::DISABLED
,
250 types_to_remove
, &config_state_map
);
251 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
252 sync_driver::BackendDataTypeConfigurer::UNREADY
,
253 types_to_unapply
, &config_state_map
);
255 types_to_add
.PutAll(syncer::ControlTypes());
256 syncer::ModelTypeSet ready_types
= backend_
->ConfigureDataTypes(
257 syncer::CONFIGURE_REASON_RECONFIGURATION
, config_state_map
,
258 base::Bind(&SyncBackendHostTest::DownloadReady
, base::Unretained(this)),
259 base::Bind(&SyncBackendHostTest::OnDownloadRetry
,
260 base::Unretained(this)));
261 base::RunLoop run_loop
;
262 BrowserThread::PostDelayedTask(BrowserThread::UI
, FROM_HERE
,
263 run_loop
.QuitClosure(),
264 TestTimeouts::action_timeout());
269 void IssueRefreshRequest(syncer::ModelTypeSet types
) {
270 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
272 content::NotificationService::current()->Notify(
273 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL
,
274 content::Source
<Profile
>(profile_
),
275 content::Details
<syncer::ModelTypeSet
>(&types
));
279 void DownloadReady(syncer::ModelTypeSet succeeded_types
,
280 syncer::ModelTypeSet failed_types
) {
281 base::MessageLoop::current()->Quit();
284 void OnDownloadRetry() {
288 content::TestBrowserThreadBundle thread_bundle_
;
289 StrictMock
<MockSyncFrontend
> mock_frontend_
;
290 syncer::SyncCredentials credentials_
;
291 TestingProfileManager profile_manager_
;
292 TestingProfile
* profile_
;
293 syncer::TestUnrecoverableErrorHandler test_unrecoverable_error_handler_
;
294 scoped_ptr
<sync_driver::SyncPrefs
> sync_prefs_
;
295 scoped_ptr
<SyncBackendHostImpl
> backend_
;
296 scoped_ptr
<FakeSyncManagerFactory
> fake_manager_factory_
;
297 FakeSyncManager
* fake_manager_
;
298 syncer::ModelTypeSet enabled_types_
;
299 scoped_ptr
<syncer::NetworkResources
> network_resources_
;
300 scoped_ptr
<syncer::SyncEncryptionHandler::NigoriState
> saved_nigori_state_
;
303 // Test basic initialization with no initial types (first time initialization).
304 // Only the nigori should be configured.
305 TEST_F(SyncBackendHostTest
, InitShutdown
) {
306 InitializeBackend(true);
307 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
308 syncer::ControlTypes()));
309 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
310 syncer::ControlTypes()));
311 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
312 syncer::ControlTypes()).Empty());
315 // Test first time sync scenario. All types should be properly configured.
316 TEST_F(SyncBackendHostTest
, FirstTimeSync
) {
317 InitializeBackend(true);
318 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
319 syncer::ControlTypes()));
320 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
321 syncer::ControlTypes()));
322 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
323 syncer::ControlTypes()).Empty());
325 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
326 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
327 syncer::ModelTypeSet());
328 // Nigori is always downloaded so won't be ready.
329 EXPECT_TRUE(ready_types
.Equals(syncer::Difference(
330 syncer::ControlTypes(),
331 syncer::ModelTypeSet(syncer::NIGORI
))));
332 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
333 Difference(enabled_types_
, syncer::ControlTypes())));
334 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
335 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
336 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
337 enabled_types_
).Empty());
340 // Test the restart after setting up sync scenario. No enabled types should be
341 // downloaded or cleaned.
342 TEST_F(SyncBackendHostTest
, Restart
) {
343 sync_prefs_
->SetSyncSetupCompleted();
344 syncer::ModelTypeSet all_but_nigori
= enabled_types_
;
345 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
346 fake_manager_factory_
->set_initial_sync_ended_types(enabled_types_
);
347 InitializeBackend(true);
348 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
349 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
350 enabled_types_
).Empty());
351 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
352 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
353 enabled_types_
).Empty());
355 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
356 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
357 syncer::ModelTypeSet());
358 EXPECT_TRUE(ready_types
.Equals(enabled_types_
));
359 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
360 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
361 enabled_types_
).Empty());
362 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
363 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
364 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
365 enabled_types_
).Empty());
368 // Test a sync restart scenario where some types had never finished configuring.
369 // The partial types should be purged, then reconfigured properly.
370 TEST_F(SyncBackendHostTest
, PartialTypes
) {
371 sync_prefs_
->SetSyncSetupCompleted();
372 // Set sync manager behavior before passing it down. All types have progress
373 // markers, but nigori and bookmarks are missing initial sync ended.
374 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
375 syncer::ModelTypeSet full_types
=
376 Difference(enabled_types_
, partial_types
);
377 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
378 fake_manager_factory_
->set_initial_sync_ended_types(full_types
);
380 // Bringing up the backend should purge all partial types, then proceed to
381 // download the Nigori.
382 InitializeBackend(true);
383 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
384 syncer::ModelTypeSet(syncer::NIGORI
)));
385 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
386 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
387 Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
388 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
389 enabled_types_
).Equals(
390 Difference(partial_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
392 // Now do the actual configuration, which should download and apply bookmarks.
393 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
394 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
395 syncer::ModelTypeSet());
396 EXPECT_TRUE(ready_types
.Equals(full_types
));
397 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
398 enabled_types_
).Empty());
399 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
401 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
402 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
403 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
404 enabled_types_
).Empty());
407 // Test the behavior when we lose the sync db. Although we already have types
408 // enabled, we should re-download all of them because we lost their data.
409 TEST_F(SyncBackendHostTest
, LostDB
) {
410 sync_prefs_
->SetSyncSetupCompleted();
411 // Initialization should fetch the Nigori node. Everything else should be
413 InitializeBackend(true);
414 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
415 syncer::ModelTypeSet(syncer::ControlTypes())));
416 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
417 syncer::ModelTypeSet(syncer::ControlTypes())));
418 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
419 enabled_types_
).Equals(
420 Difference(enabled_types_
, syncer::ControlTypes())));
422 // The database was empty, so any cleaning is entirely optional. We want to
423 // reset this value before running the next part of the test, though.
424 fake_manager_
->GetAndResetCleanedTypes();
426 // The actual configuration should redownload and apply all the enabled types.
427 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
428 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
429 syncer::ModelTypeSet());
430 // Nigori is always downloaded so won't be ready.
431 EXPECT_TRUE(ready_types
.Equals(syncer::Difference(
432 syncer::ControlTypes(),
433 syncer::ModelTypeSet(syncer::NIGORI
))));
434 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
435 Difference(enabled_types_
, syncer::ControlTypes())));
436 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
437 enabled_types_
).Empty());
438 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
439 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
440 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
441 enabled_types_
).Empty());
444 TEST_F(SyncBackendHostTest
, DisableTypes
) {
445 // Simulate first time sync.
446 InitializeBackend(true);
447 fake_manager_
->GetAndResetCleanedTypes();
448 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
449 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
450 syncer::ModelTypeSet());
451 // Nigori is always downloaded so won't be ready.
452 EXPECT_TRUE(ready_types
.Equals(syncer::Difference(
453 syncer::ControlTypes(),
454 syncer::ModelTypeSet(syncer::NIGORI
))));
455 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
457 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
458 enabled_types_
).Empty());
459 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
460 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
461 enabled_types_
).Empty());
463 // Then disable two datatypes.
464 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
465 syncer::SEARCH_ENGINES
);
466 syncer::ModelTypeSet old_types
= enabled_types_
;
467 enabled_types_
.RemoveAll(disabled_types
);
468 ready_types
= ConfigureDataTypes(
469 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
470 syncer::ModelTypeSet());
472 // Only those datatypes disabled should be cleaned. Nothing should be
474 EXPECT_TRUE(ready_types
.Equals(enabled_types_
));
475 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
476 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
477 old_types
).Equals(disabled_types
));
478 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
479 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
480 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
481 enabled_types_
).Empty());
484 TEST_F(SyncBackendHostTest
, AddTypes
) {
485 // Simulate first time sync.
486 InitializeBackend(true);
487 fake_manager_
->GetAndResetCleanedTypes();
488 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
489 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
490 syncer::ModelTypeSet());
491 // Nigori is always downloaded so won't be ready.
492 EXPECT_TRUE(ready_types
.Equals(syncer::Difference(
493 syncer::ControlTypes(),
494 syncer::ModelTypeSet(syncer::NIGORI
))));
495 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
497 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
498 enabled_types_
).Empty());
499 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
500 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
501 enabled_types_
).Empty());
503 // Then add two datatypes.
504 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
506 enabled_types_
.PutAll(new_types
);
507 ready_types
= ConfigureDataTypes(
508 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
509 syncer::ModelTypeSet());
511 // Only those datatypes added should be downloaded (plus nigori). Nothing
512 // should be cleaned aside from the disabled types.
513 new_types
.Put(syncer::NIGORI
);
515 ready_types
.Equals(syncer::Difference(enabled_types_
, new_types
)));
516 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(new_types
));
517 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
518 enabled_types_
).Empty());
519 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
520 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
521 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
522 enabled_types_
).Empty());
525 // And and disable in the same configuration.
526 TEST_F(SyncBackendHostTest
, AddDisableTypes
) {
527 // Simulate first time sync.
528 InitializeBackend(true);
529 fake_manager_
->GetAndResetCleanedTypes();
530 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
531 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
532 syncer::ModelTypeSet());
533 // Nigori is always downloaded so won't be ready.
534 EXPECT_TRUE(ready_types
.Equals(syncer::Difference(
535 syncer::ControlTypes(),
536 syncer::ModelTypeSet(syncer::NIGORI
))));
537 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
539 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
540 enabled_types_
).Empty());
541 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
542 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
543 enabled_types_
).Empty());
545 // Then add two datatypes.
546 syncer::ModelTypeSet old_types
= enabled_types_
;
547 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
548 syncer::SEARCH_ENGINES
);
549 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
551 enabled_types_
.PutAll(new_types
);
552 enabled_types_
.RemoveAll(disabled_types
);
553 ready_types
= ConfigureDataTypes(
554 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
555 syncer::ModelTypeSet());
557 // Only those datatypes added should be downloaded (plus nigori). Nothing
558 // should be cleaned aside from the disabled types.
559 new_types
.Put(syncer::NIGORI
);
561 ready_types
.Equals(syncer::Difference(enabled_types_
, new_types
)));
562 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(new_types
));
563 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
564 old_types
).Equals(disabled_types
));
565 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
566 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
567 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
568 old_types
).Equals(disabled_types
));
571 // Test restarting the browser to newly supported datatypes. The new datatypes
572 // should be downloaded on the configuration after backend initialization.
573 TEST_F(SyncBackendHostTest
, NewlySupportedTypes
) {
574 sync_prefs_
->SetSyncSetupCompleted();
575 // Set sync manager behavior before passing it down. All types have progress
576 // markers and initial sync ended except the new types.
577 syncer::ModelTypeSet old_types
= enabled_types_
;
578 fake_manager_factory_
->set_progress_marker_types(old_types
);
579 fake_manager_factory_
->set_initial_sync_ended_types(old_types
);
580 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
581 syncer::EXTENSION_SETTINGS
);
582 enabled_types_
.PutAll(new_types
);
585 InitializeBackend(true);
586 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
587 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
589 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(old_types
));
590 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
591 enabled_types_
).Equals(new_types
));
593 // Downloads and applies the new types (plus nigori).
594 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
595 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
596 syncer::ModelTypeSet());
598 new_types
.Put(syncer::NIGORI
);
599 EXPECT_TRUE(ready_types
.Equals(
600 syncer::Difference(old_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
601 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(new_types
));
602 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
603 enabled_types_
).Empty());
604 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
605 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
606 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
607 enabled_types_
).Empty());
610 // Test the newly supported types scenario, but with the presence of partial
611 // types as well. Both partial and newly supported types should be downloaded
612 // the configuration.
613 TEST_F(SyncBackendHostTest
, NewlySupportedTypesWithPartialTypes
) {
614 sync_prefs_
->SetSyncSetupCompleted();
615 // Set sync manager behavior before passing it down. All types have progress
616 // markers and initial sync ended except the new types.
617 syncer::ModelTypeSet old_types
= enabled_types_
;
618 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
619 syncer::ModelTypeSet full_types
=
620 Difference(enabled_types_
, partial_types
);
621 fake_manager_factory_
->set_progress_marker_types(old_types
);
622 fake_manager_factory_
->set_initial_sync_ended_types(full_types
);
623 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
624 syncer::EXTENSION_SETTINGS
);
625 enabled_types_
.PutAll(new_types
);
627 // Purge the partial types. The nigori will be among the purged types, but
628 // the syncer will re-download it by the time the initialization is complete.
629 InitializeBackend(true);
630 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
631 syncer::ModelTypeSet(syncer::NIGORI
)));
632 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
633 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
634 syncer::Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
635 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
636 enabled_types_
).Equals(Union(new_types
, Difference(
637 partial_types
, syncer::ModelTypeSet(syncer::NIGORI
)))));
639 // Downloads and applies the new types and partial types (which includes
641 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
642 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
643 syncer::ModelTypeSet());
644 EXPECT_TRUE(ready_types
.Equals(full_types
));
645 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
646 Union(new_types
, partial_types
)));
647 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
648 enabled_types_
).Empty());
649 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
650 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
651 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
652 enabled_types_
).Empty());
655 // Verify that downloading control types only downloads those types that do
656 // not have initial sync ended set.
657 TEST_F(SyncBackendHostTest
, DownloadControlTypes
) {
658 sync_prefs_
->SetSyncSetupCompleted();
659 // Set sync manager behavior before passing it down. Experiments and device
660 // info are new types without progress markers or initial sync ended, while
661 // all other types have been fully downloaded and applied.
662 syncer::ModelTypeSet
new_types(syncer::EXPERIMENTS
, syncer::NIGORI
);
663 syncer::ModelTypeSet old_types
=
664 Difference(enabled_types_
, new_types
);
665 fake_manager_factory_
->set_progress_marker_types(old_types
);
666 fake_manager_factory_
->set_initial_sync_ended_types(old_types
);
668 // Bringing up the backend should download the new types without downloading
670 InitializeBackend(true);
671 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(new_types
));
672 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().Equals(
673 Difference(syncer::ModelTypeSet::All(),
675 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
676 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
677 enabled_types_
).Empty());
680 // Fail to download control types. It's believed that there is a server bug
681 // which can allow this to happen (crbug.com/164288). The sync backend host
682 // should detect this condition and fail to initialize the backend.
684 // The failure is "silent" in the sense that the GetUpdates request appears to
685 // be successful, but it returned no results. This means that the usual
686 // download retry logic will not be invoked.
687 TEST_F(SyncBackendHostTest
, SilentlyFailToDownloadControlTypes
) {
688 fake_manager_factory_
->set_configure_fail_types(syncer::ModelTypeSet::All());
689 InitializeBackend(false);
692 // Test that local refresh requests are delivered to sync.
693 TEST_F(SyncBackendHostTest
, ForwardLocalRefreshRequest
) {
694 InitializeBackend(true);
696 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
697 IssueRefreshRequest(set1
);
698 fake_manager_
->WaitForSyncThread();
699 EXPECT_TRUE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
701 syncer::ModelTypeSet set2
= syncer::ModelTypeSet(syncer::SESSIONS
);
702 IssueRefreshRequest(set2
);
703 fake_manager_
->WaitForSyncThread();
704 EXPECT_TRUE(set2
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
707 // Test that local invalidations issued before sync is initialized are ignored.
708 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestEarly
) {
709 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
710 IssueRefreshRequest(set1
);
712 InitializeBackend(true);
714 fake_manager_
->WaitForSyncThread();
715 EXPECT_FALSE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
718 // Test that local invalidations issued while sync is shutting down are ignored.
719 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestLate
) {
720 InitializeBackend(true);
722 backend_
->StopSyncingForShutdown();
724 syncer::ModelTypeSet types
= syncer::ModelTypeSet::All();
725 IssueRefreshRequest(types
);
726 fake_manager_
->WaitForSyncThread();
727 EXPECT_FALSE(types
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
729 backend_
->Shutdown(syncer::STOP_SYNC
);
733 // Test that configuration on signin sends the proper GU source.
734 TEST_F(SyncBackendHostTest
, DownloadControlTypesNewClient
) {
735 InitializeBackend(true);
736 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT
,
737 fake_manager_
->GetAndResetConfigureReason());
740 // Test that configuration on restart sends the proper GU source.
741 TEST_F(SyncBackendHostTest
, DownloadControlTypesRestart
) {
742 sync_prefs_
->SetSyncSetupCompleted();
743 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
744 fake_manager_factory_
->set_initial_sync_ended_types(enabled_types_
);
745 InitializeBackend(true);
746 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE
,
747 fake_manager_
->GetAndResetConfigureReason());
750 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
751 // setup hasn't been completed. This test ensures that cleanup happens.
752 TEST_F(SyncBackendHostTest
, TestStartupWithOldSyncData
) {
753 const char* nonsense
= "slon";
754 base::FilePath temp_directory
=
755 profile_
->GetPath().Append(base::FilePath(kTestSyncDir
));
756 base::FilePath sync_file
= temp_directory
.AppendASCII("SyncData.sqlite3");
757 ASSERT_TRUE(base::CreateDirectory(temp_directory
));
758 ASSERT_NE(-1, base::WriteFile(sync_file
, nonsense
, strlen(nonsense
)));
760 InitializeBackend(true);
762 EXPECT_FALSE(base::PathExists(sync_file
));
765 // If bookmarks encounter an error that results in disabling without purging
766 // (such as when the type is unready), and then is explicitly disabled, the
767 // SyncBackendHost needs to tell the manager to purge the type, even though
768 // it's already disabled (crbug.com/386778).
769 TEST_F(SyncBackendHostTest
, DisableThenPurgeType
) {
770 syncer::ModelTypeSet
error_types(syncer::BOOKMARKS
);
772 InitializeBackend(true);
774 // First enable the types.
775 syncer::ModelTypeSet ready_types
= ConfigureDataTypes(
776 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
777 syncer::ModelTypeSet());
779 // Nigori is always downloaded so won't be ready.
780 EXPECT_TRUE(ready_types
.Equals(syncer::Difference(
781 syncer::ControlTypes(),
782 syncer::ModelTypeSet(syncer::NIGORI
))));
784 // Then mark the error types as unready (disables without purging).
785 ready_types
= ConfigureDataTypes(
786 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
789 ready_types
.Equals(syncer::Difference(enabled_types_
, error_types
)));
790 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
791 error_types
).Empty());
793 // Lastly explicitly disable the error types, which should result in a purge.
794 enabled_types_
.RemoveAll(error_types
);
795 ready_types
= ConfigureDataTypes(
796 enabled_types_
, Difference(syncer::ModelTypeSet::All(), enabled_types_
),
797 syncer::ModelTypeSet());
799 ready_types
.Equals(syncer::Difference(enabled_types_
, error_types
)));
800 EXPECT_FALSE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
801 error_types
).Empty());
804 // Test that a call to ClearServerData is forwarded to the underlying
806 TEST_F(SyncBackendHostTest
, ClearServerDataCallsAreForwarded
) {
807 InitializeBackend(true);
808 syncer::CallbackCounter callback_counter
;
809 backend_
->ClearServerData(base::Bind(&syncer::CallbackCounter::Callback
,
810 base::Unretained(&callback_counter
)));
811 fake_manager_
->WaitForSyncThread();
812 EXPECT_EQ(1, callback_counter
.times_called());
815 // Ensure that redundant invalidations are ignored and that the most recent
816 // set of invalidation version is persisted across restarts.
817 TEST_F(SyncBackendHostTest
, IgnoreOldInvalidations
) {
818 // Set up some old persisted invalidations.
819 std::map
<syncer::ModelType
, int64
> invalidation_versions
;
820 invalidation_versions
[syncer::BOOKMARKS
] = 20;
821 sync_prefs_
->UpdateInvalidationVersions(invalidation_versions
);
822 InitializeBackend(true);
823 EXPECT_EQ(0, fake_manager_
->GetInvalidationCount());
825 // Receiving an invalidation with an old version should do nothing.
826 syncer::ObjectIdInvalidationMap invalidation_map
;
827 std::string notification_type
;
828 syncer::RealModelTypeToNotificationType(syncer::BOOKMARKS
,
830 invalidation_map
.Insert(syncer::Invalidation::Init(
831 invalidation::ObjectId(0, notification_type
), 10, "payload"));
832 backend_
->OnIncomingInvalidation(invalidation_map
);
833 fake_manager_
->WaitForSyncThread();
834 EXPECT_EQ(0, fake_manager_
->GetInvalidationCount());
836 // Invalidations with new versions should be acted upon.
837 invalidation_map
.Insert(syncer::Invalidation::Init(
838 invalidation::ObjectId(0, notification_type
), 30, "payload"));
839 backend_
->OnIncomingInvalidation(invalidation_map
);
840 fake_manager_
->WaitForSyncThread();
841 EXPECT_EQ(1, fake_manager_
->GetInvalidationCount());
843 // Invalidation for new data types should be acted on.
844 syncer::RealModelTypeToNotificationType(syncer::SESSIONS
, ¬ification_type
);
845 invalidation_map
.Insert(syncer::Invalidation::Init(
846 invalidation::ObjectId(0, notification_type
), 10, "payload"));
847 backend_
->OnIncomingInvalidation(invalidation_map
);
848 fake_manager_
->WaitForSyncThread();
849 EXPECT_EQ(2, fake_manager_
->GetInvalidationCount());
851 // But redelivering that same invalidation should be ignored.
852 backend_
->OnIncomingInvalidation(invalidation_map
);
853 fake_manager_
->WaitForSyncThread();
854 EXPECT_EQ(2, fake_manager_
->GetInvalidationCount());
856 // If an invalidation with an unknown version is received, it should be
857 // acted on, but should not affect the persisted versions.
858 invalidation_map
.Insert(syncer::Invalidation::InitUnknownVersion(
859 invalidation::ObjectId(0, notification_type
)));
860 backend_
->OnIncomingInvalidation(invalidation_map
);
861 fake_manager_
->WaitForSyncThread();
862 EXPECT_EQ(3, fake_manager_
->GetInvalidationCount());
864 // Verify that the invalidation versions were updated in the prefs.
865 invalidation_versions
[syncer::BOOKMARKS
] = 30;
866 invalidation_versions
[syncer::SESSIONS
] = 10;
867 std::map
<syncer::ModelType
, int64
> persisted_invalidation_versions
;
868 sync_prefs_
->GetInvalidationVersions(&persisted_invalidation_versions
);
869 EXPECT_EQ(invalidation_versions
.size(),
870 persisted_invalidation_versions
.size());
871 for (auto iter
: persisted_invalidation_versions
) {
872 EXPECT_EQ(invalidation_versions
[iter
.first
], iter
.second
);
878 } // namespace browser_sync