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/invalidator_state.h"
22 #include "components/invalidation/invalidator_storage.h"
23 #include "components/invalidation/profile_invalidation_provider.h"
24 #include "components/sync_driver/device_info.h"
25 #include "components/sync_driver/sync_frontend.h"
26 #include "components/sync_driver/sync_prefs.h"
27 #include "content/public/browser/notification_service.h"
28 #include "content/public/test/test_browser_thread_bundle.h"
29 #include "content/public/test/test_utils.h"
30 #include "google/cacheinvalidation/include/types.h"
31 #include "google_apis/gaia/gaia_constants.h"
32 #include "net/url_request/test_url_fetcher_factory.h"
33 #include "sync/internal_api/public/base/model_type.h"
34 #include "sync/internal_api/public/engine/model_safe_worker.h"
35 #include "sync/internal_api/public/http_bridge_network_resources.h"
36 #include "sync/internal_api/public/network_resources.h"
37 #include "sync/internal_api/public/sessions/commit_counters.h"
38 #include "sync/internal_api/public/sessions/status_counters.h"
39 #include "sync/internal_api/public/sessions/update_counters.h"
40 #include "sync/internal_api/public/sync_manager_factory.h"
41 #include "sync/internal_api/public/test/fake_sync_manager.h"
42 #include "sync/internal_api/public/util/experiments.h"
43 #include "sync/protocol/encryption.pb.h"
44 #include "sync/protocol/sync_protocol_error.h"
45 #include "sync/util/test_unrecoverable_error_handler.h"
46 #include "testing/gmock/include/gmock/gmock.h"
47 #include "testing/gtest/include/gtest/gtest.h"
50 using content::BrowserThread
;
51 using syncer::FakeSyncManager
;
52 using syncer::SyncManager
;
53 using ::testing::InvokeWithoutArgs
;
54 using ::testing::StrictMock
;
57 namespace browser_sync
{
61 const char kTestProfileName
[] = "test-profile";
63 static const base::FilePath::CharType kTestSyncDir
[] =
64 FILE_PATH_LITERAL("sync-test");
66 ACTION_P(Signal
, event
) {
70 void QuitMessageLoop() {
71 base::MessageLoop::current()->Quit();
74 class MockSyncFrontend
: public sync_driver::SyncFrontend
{
76 virtual ~MockSyncFrontend() {}
80 void(const syncer::WeakHandle
<syncer::JsBackend
>&,
81 const syncer::WeakHandle
<syncer::DataTypeDebugInfoListener
>&,
84 MOCK_METHOD0(OnSyncCycleCompleted
, void());
85 MOCK_METHOD1(OnConnectionStatusChange
,
86 void(syncer::ConnectionStatus status
));
87 MOCK_METHOD0(OnClearServerDataSucceeded
, void());
88 MOCK_METHOD0(OnClearServerDataFailed
, void());
89 MOCK_METHOD2(OnPassphraseRequired
,
90 void(syncer::PassphraseRequiredReason
,
91 const sync_pb::EncryptedData
&));
92 MOCK_METHOD0(OnPassphraseAccepted
, void());
93 MOCK_METHOD2(OnEncryptedTypesChanged
,
94 void(syncer::ModelTypeSet
, bool));
95 MOCK_METHOD0(OnEncryptionComplete
, void());
96 MOCK_METHOD1(OnMigrationNeededForTypes
, void(syncer::ModelTypeSet
));
97 MOCK_METHOD1(OnProtocolEvent
, void(const syncer::ProtocolEvent
&));
98 MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated
,
99 void(syncer::ModelType
, const syncer::CommitCounters
&));
100 MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated
,
101 void(syncer::ModelType
, const syncer::UpdateCounters
&));
102 MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated
,
103 void(syncer::ModelType
, const syncer::StatusCounters
&));
104 MOCK_METHOD1(OnExperimentsChanged
,
105 void(const syncer::Experiments
&));
106 MOCK_METHOD1(OnActionableError
,
107 void(const syncer::SyncProtocolError
& sync_error
));
108 MOCK_METHOD0(OnSyncConfigureRetry
, void());
111 class FakeSyncManagerFactory
: public syncer::SyncManagerFactory
{
113 explicit FakeSyncManagerFactory(FakeSyncManager
** fake_manager
)
114 : SyncManagerFactory(NORMAL
),
115 fake_manager_(fake_manager
) {
116 *fake_manager_
= NULL
;
118 ~FakeSyncManagerFactory() override
{}
120 // SyncManagerFactory implementation. Called on the sync thread.
121 scoped_ptr
<SyncManager
> CreateSyncManager(std::string name
) override
{
122 *fake_manager_
= new FakeSyncManager(initial_sync_ended_types_
,
123 progress_marker_types_
,
124 configure_fail_types_
);
125 return scoped_ptr
<SyncManager
>(*fake_manager_
);
128 void set_initial_sync_ended_types(syncer::ModelTypeSet types
) {
129 initial_sync_ended_types_
= types
;
132 void set_progress_marker_types(syncer::ModelTypeSet types
) {
133 progress_marker_types_
= types
;
136 void set_configure_fail_types(syncer::ModelTypeSet types
) {
137 configure_fail_types_
= types
;
141 syncer::ModelTypeSet initial_sync_ended_types_
;
142 syncer::ModelTypeSet progress_marker_types_
;
143 syncer::ModelTypeSet configure_fail_types_
;
144 FakeSyncManager
** fake_manager_
;
147 class SyncBackendHostTest
: public testing::Test
{
149 SyncBackendHostTest()
150 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD
),
151 profile_manager_(TestingBrowserProcess::GetGlobal()),
152 fake_manager_(NULL
) {}
154 virtual ~SyncBackendHostTest() {}
156 virtual void SetUp() override
{
157 ASSERT_TRUE(profile_manager_
.SetUp());
158 profile_
= profile_manager_
.CreateTestingProfile(kTestProfileName
);
159 sync_prefs_
.reset(new sync_driver::SyncPrefs(profile_
->GetPrefs()));
160 backend_
.reset(new SyncBackendHostImpl(
161 profile_
->GetDebugName(),
163 invalidation::ProfileInvalidationProviderFactory::GetForProfile(
164 profile_
)->GetInvalidationService(),
165 sync_prefs_
->AsWeakPtr(),
166 base::FilePath(kTestSyncDir
)));
167 credentials_
.email
= "user@example.com";
168 credentials_
.sync_token
= "sync_token";
169 credentials_
.scope_set
.insert(GaiaConstants::kChromeSyncOAuth2Scope
);
171 fake_manager_factory_
.reset(new FakeSyncManagerFactory(&fake_manager_
));
173 // These types are always implicitly enabled.
174 enabled_types_
.PutAll(syncer::ControlTypes());
176 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
177 // Registrar removing them if it can't find their model workers.
178 enabled_types_
.Put(syncer::BOOKMARKS
);
179 enabled_types_
.Put(syncer::NIGORI
);
180 enabled_types_
.Put(syncer::DEVICE_INFO
);
181 enabled_types_
.Put(syncer::PREFERENCES
);
182 enabled_types_
.Put(syncer::SESSIONS
);
183 enabled_types_
.Put(syncer::SEARCH_ENGINES
);
184 enabled_types_
.Put(syncer::AUTOFILL
);
185 enabled_types_
.Put(syncer::EXPERIMENTS
);
187 network_resources_
.reset(new syncer::HttpBridgeNetworkResources());
190 virtual void TearDown() override
{
192 backend_
->StopSyncingForShutdown();
193 backend_
->Shutdown(syncer::STOP_SYNC
);
198 profile_manager_
.DeleteTestingProfile(kTestProfileName
);
199 // Pump messages posted by the sync thread (which may end up
200 // posting on the IO thread).
201 base::RunLoop().RunUntilIdle();
202 content::RunAllPendingInMessageLoop(BrowserThread::IO
);
203 // Pump any messages posted by the IO thread.
204 base::RunLoop().RunUntilIdle();
207 // Synchronously initializes the backend.
208 void InitializeBackend(bool expect_success
) {
209 EXPECT_CALL(mock_frontend_
, OnBackendInitialized(_
, _
, _
, expect_success
)).
210 WillOnce(InvokeWithoutArgs(QuitMessageLoop
));
211 backend_
->Initialize(
213 scoped_ptr
<base::Thread
>(),
214 syncer::WeakHandle
<syncer::JsEventHandler
>(),
218 fake_manager_factory_
.Pass(),
219 make_scoped_ptr(new syncer::TestUnrecoverableErrorHandler
),
221 network_resources_
.get());
222 base::RunLoop run_loop
;
223 BrowserThread::PostDelayedTask(BrowserThread::UI
, FROM_HERE
,
224 run_loop
.QuitClosure(),
225 TestTimeouts::action_timeout());
227 // |fake_manager_factory_|'s fake_manager() is set on the sync
228 // thread, but we can rely on the message loop barriers to
229 // guarantee that we see the updated value.
230 DCHECK(fake_manager_
);
233 // Synchronously configures the backend's datatypes.
234 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add
,
235 syncer::ModelTypeSet types_to_remove
,
236 syncer::ModelTypeSet types_to_unapply
) {
237 sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap
239 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
240 sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE
,
243 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
244 sync_driver::BackendDataTypeConfigurer::DISABLED
,
245 types_to_remove
, &config_state_map
);
246 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
247 sync_driver::BackendDataTypeConfigurer::UNREADY
,
248 types_to_unapply
, &config_state_map
);
250 types_to_add
.PutAll(syncer::ControlTypes());
251 backend_
->ConfigureDataTypes(
252 syncer::CONFIGURE_REASON_RECONFIGURATION
,
254 base::Bind(&SyncBackendHostTest::DownloadReady
,
255 base::Unretained(this)),
256 base::Bind(&SyncBackendHostTest::OnDownloadRetry
,
257 base::Unretained(this)));
258 base::RunLoop run_loop
;
259 BrowserThread::PostDelayedTask(BrowserThread::UI
, FROM_HERE
,
260 run_loop
.QuitClosure(),
261 TestTimeouts::action_timeout());
265 void IssueRefreshRequest(syncer::ModelTypeSet types
) {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
268 content::NotificationService::current()->Notify(
269 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL
,
270 content::Source
<Profile
>(profile_
),
271 content::Details
<syncer::ModelTypeSet
>(&types
));
275 void DownloadReady(syncer::ModelTypeSet succeeded_types
,
276 syncer::ModelTypeSet failed_types
) {
277 base::MessageLoop::current()->Quit();
280 void OnDownloadRetry() {
284 content::TestBrowserThreadBundle thread_bundle_
;
285 StrictMock
<MockSyncFrontend
> mock_frontend_
;
286 syncer::SyncCredentials credentials_
;
287 TestingProfileManager profile_manager_
;
288 TestingProfile
* profile_
;
289 scoped_ptr
<sync_driver::SyncPrefs
> sync_prefs_
;
290 scoped_ptr
<SyncBackendHost
> backend_
;
291 scoped_ptr
<FakeSyncManagerFactory
> fake_manager_factory_
;
292 FakeSyncManager
* fake_manager_
;
293 syncer::ModelTypeSet enabled_types_
;
294 scoped_ptr
<syncer::NetworkResources
> network_resources_
;
297 // Test basic initialization with no initial types (first time initialization).
298 // Only the nigori should be configured.
299 TEST_F(SyncBackendHostTest
, InitShutdown
) {
300 InitializeBackend(true);
301 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
302 syncer::ControlTypes()));
303 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
304 syncer::ControlTypes()));
305 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
306 syncer::ControlTypes()).Empty());
309 // Test first time sync scenario. All types should be properly configured.
310 TEST_F(SyncBackendHostTest
, FirstTimeSync
) {
311 InitializeBackend(true);
312 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
313 syncer::ControlTypes()));
314 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
315 syncer::ControlTypes()));
316 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
317 syncer::ControlTypes()).Empty());
319 ConfigureDataTypes(enabled_types_
,
320 Difference(syncer::ModelTypeSet::All(),
322 syncer::ModelTypeSet());
323 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
324 Difference(enabled_types_
, syncer::ControlTypes())));
325 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
326 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
327 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
328 enabled_types_
).Empty());
331 // Test the restart after setting up sync scenario. No enabled types should be
332 // downloaded or cleaned.
333 TEST_F(SyncBackendHostTest
, Restart
) {
334 sync_prefs_
->SetSyncSetupCompleted();
335 syncer::ModelTypeSet all_but_nigori
= enabled_types_
;
336 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
337 fake_manager_factory_
->set_initial_sync_ended_types(enabled_types_
);
338 InitializeBackend(true);
339 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
340 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
341 enabled_types_
).Empty());
342 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
343 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
344 enabled_types_
).Empty());
346 ConfigureDataTypes(enabled_types_
,
347 Difference(syncer::ModelTypeSet::All(),
349 syncer::ModelTypeSet());
350 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
351 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
352 enabled_types_
).Empty());
353 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
354 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
355 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
356 enabled_types_
).Empty());
359 // Test a sync restart scenario where some types had never finished configuring.
360 // The partial types should be purged, then reconfigured properly.
361 TEST_F(SyncBackendHostTest
, PartialTypes
) {
362 sync_prefs_
->SetSyncSetupCompleted();
363 // Set sync manager behavior before passing it down. All types have progress
364 // markers, but nigori and bookmarks are missing initial sync ended.
365 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
366 syncer::ModelTypeSet full_types
=
367 Difference(enabled_types_
, partial_types
);
368 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
369 fake_manager_factory_
->set_initial_sync_ended_types(full_types
);
371 // Bringing up the backend should purge all partial types, then proceed to
372 // download the Nigori.
373 InitializeBackend(true);
374 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
375 syncer::ModelTypeSet(syncer::NIGORI
)));
376 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
377 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
378 Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
379 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
380 enabled_types_
).Equals(
381 Difference(partial_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
383 // Now do the actual configuration, which should download and apply bookmarks.
384 ConfigureDataTypes(enabled_types_
,
385 Difference(syncer::ModelTypeSet::All(),
387 syncer::ModelTypeSet());
388 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
389 enabled_types_
).Empty());
390 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
392 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
393 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
394 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
395 enabled_types_
).Empty());
398 // Test the behavior when we lose the sync db. Although we already have types
399 // enabled, we should re-download all of them because we lost their data.
400 TEST_F(SyncBackendHostTest
, LostDB
) {
401 sync_prefs_
->SetSyncSetupCompleted();
402 // Initialization should fetch the Nigori node. Everything else should be
404 InitializeBackend(true);
405 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
406 syncer::ModelTypeSet(syncer::ControlTypes())));
407 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
408 syncer::ModelTypeSet(syncer::ControlTypes())));
409 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
410 enabled_types_
).Equals(
411 Difference(enabled_types_
, syncer::ControlTypes())));
413 // The database was empty, so any cleaning is entirely optional. We want to
414 // reset this value before running the next part of the test, though.
415 fake_manager_
->GetAndResetCleanedTypes();
417 // The actual configuration should redownload and apply all the enabled types.
418 ConfigureDataTypes(enabled_types_
,
419 Difference(syncer::ModelTypeSet::All(),
421 syncer::ModelTypeSet());
422 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
423 Difference(enabled_types_
, syncer::ControlTypes())));
424 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
425 enabled_types_
).Empty());
426 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
427 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
428 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
429 enabled_types_
).Empty());
432 TEST_F(SyncBackendHostTest
, DisableTypes
) {
433 // Simulate first time sync.
434 InitializeBackend(true);
435 fake_manager_
->GetAndResetCleanedTypes();
436 ConfigureDataTypes(enabled_types_
,
437 Difference(syncer::ModelTypeSet::All(),
439 syncer::ModelTypeSet());
440 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
442 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
443 enabled_types_
).Empty());
444 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
445 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
446 enabled_types_
).Empty());
448 // Then disable two datatypes.
449 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
450 syncer::SEARCH_ENGINES
);
451 syncer::ModelTypeSet old_types
= enabled_types_
;
452 enabled_types_
.RemoveAll(disabled_types
);
453 ConfigureDataTypes(enabled_types_
,
454 Difference(syncer::ModelTypeSet::All(),
456 syncer::ModelTypeSet());
458 // Only those datatypes disabled should be cleaned. Nothing should be
460 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
461 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
462 old_types
).Equals(disabled_types
));
463 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
464 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
465 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
466 enabled_types_
).Empty());
469 TEST_F(SyncBackendHostTest
, AddTypes
) {
470 // Simulate first time sync.
471 InitializeBackend(true);
472 fake_manager_
->GetAndResetCleanedTypes();
473 ConfigureDataTypes(enabled_types_
,
474 Difference(syncer::ModelTypeSet::All(),
476 syncer::ModelTypeSet());
477 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
479 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
480 enabled_types_
).Empty());
481 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
482 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
483 enabled_types_
).Empty());
485 // Then add two datatypes.
486 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
488 enabled_types_
.PutAll(new_types
);
489 ConfigureDataTypes(enabled_types_
,
490 Difference(syncer::ModelTypeSet::All(),
492 syncer::ModelTypeSet());
494 // Only those datatypes added should be downloaded (plus nigori). Nothing
495 // should be cleaned aside from the disabled types.
496 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
497 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
498 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
499 enabled_types_
).Empty());
500 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
501 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
502 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
503 enabled_types_
).Empty());
506 // And and disable in the same configuration.
507 TEST_F(SyncBackendHostTest
, AddDisableTypes
) {
508 // Simulate first time sync.
509 InitializeBackend(true);
510 fake_manager_
->GetAndResetCleanedTypes();
511 ConfigureDataTypes(enabled_types_
,
512 Difference(syncer::ModelTypeSet::All(),
514 syncer::ModelTypeSet());
515 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
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_
->GetTypesWithEmptyProgressMarkerToken(
521 enabled_types_
).Empty());
523 // Then add two datatypes.
524 syncer::ModelTypeSet old_types
= enabled_types_
;
525 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
526 syncer::SEARCH_ENGINES
);
527 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
529 enabled_types_
.PutAll(new_types
);
530 enabled_types_
.RemoveAll(disabled_types
);
531 ConfigureDataTypes(enabled_types_
,
532 Difference(syncer::ModelTypeSet::All(),
534 syncer::ModelTypeSet());
536 // Only those datatypes added should be downloaded (plus nigori). Nothing
537 // should be cleaned aside from the disabled types.
538 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
539 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
540 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
541 old_types
).Equals(disabled_types
));
542 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
543 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
544 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
545 old_types
).Equals(disabled_types
));
548 // Test restarting the browser to newly supported datatypes. The new datatypes
549 // should be downloaded on the configuration after backend initialization.
550 TEST_F(SyncBackendHostTest
, NewlySupportedTypes
) {
551 sync_prefs_
->SetSyncSetupCompleted();
552 // Set sync manager behavior before passing it down. All types have progress
553 // markers and initial sync ended except the new types.
554 syncer::ModelTypeSet old_types
= enabled_types_
;
555 fake_manager_factory_
->set_progress_marker_types(old_types
);
556 fake_manager_factory_
->set_initial_sync_ended_types(old_types
);
557 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
558 syncer::EXTENSION_SETTINGS
);
559 enabled_types_
.PutAll(new_types
);
562 InitializeBackend(true);
563 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
564 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
566 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(old_types
));
567 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
568 enabled_types_
).Equals(new_types
));
570 // Downloads and applies the new types.
571 ConfigureDataTypes(enabled_types_
,
572 Difference(syncer::ModelTypeSet::All(),
574 syncer::ModelTypeSet());
575 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
576 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
577 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
578 enabled_types_
).Empty());
579 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
580 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
581 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
582 enabled_types_
).Empty());
585 // Test the newly supported types scenario, but with the presence of partial
586 // types as well. Both partial and newly supported types should be downloaded
587 // the configuration.
588 TEST_F(SyncBackendHostTest
, NewlySupportedTypesWithPartialTypes
) {
589 sync_prefs_
->SetSyncSetupCompleted();
590 // Set sync manager behavior before passing it down. All types have progress
591 // markers and initial sync ended except the new types.
592 syncer::ModelTypeSet old_types
= enabled_types_
;
593 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
594 syncer::ModelTypeSet full_types
=
595 Difference(enabled_types_
, partial_types
);
596 fake_manager_factory_
->set_progress_marker_types(old_types
);
597 fake_manager_factory_
->set_initial_sync_ended_types(full_types
);
598 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
599 syncer::EXTENSION_SETTINGS
);
600 enabled_types_
.PutAll(new_types
);
602 // Purge the partial types. The nigori will be among the purged types, but
603 // the syncer will re-download it by the time the initialization is complete.
604 InitializeBackend(true);
605 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
606 syncer::ModelTypeSet(syncer::NIGORI
)));
607 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
608 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
609 syncer::Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
610 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
611 enabled_types_
).Equals(Union(new_types
, Difference(
612 partial_types
, syncer::ModelTypeSet(syncer::NIGORI
)))));
614 // Downloads and applies the new types and partial types (which includes
616 ConfigureDataTypes(enabled_types_
,
617 Difference(syncer::ModelTypeSet::All(),
619 syncer::ModelTypeSet());
620 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
621 Union(new_types
, partial_types
)));
622 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
623 enabled_types_
).Empty());
624 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
625 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
626 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
627 enabled_types_
).Empty());
630 // Verify that downloading control types only downloads those types that do
631 // not have initial sync ended set.
632 TEST_F(SyncBackendHostTest
, DownloadControlTypes
) {
633 sync_prefs_
->SetSyncSetupCompleted();
634 // Set sync manager behavior before passing it down. Experiments and device
635 // info are new types without progress markers or initial sync ended, while
636 // all other types have been fully downloaded and applied.
637 syncer::ModelTypeSet
new_types(syncer::EXPERIMENTS
, syncer::NIGORI
);
638 syncer::ModelTypeSet old_types
=
639 Difference(enabled_types_
, new_types
);
640 fake_manager_factory_
->set_progress_marker_types(old_types
);
641 fake_manager_factory_
->set_initial_sync_ended_types(old_types
);
643 // Bringing up the backend should download the new types without downloading
645 InitializeBackend(true);
646 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(new_types
));
647 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().Equals(
648 Difference(syncer::ModelTypeSet::All(),
650 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
651 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
652 enabled_types_
).Empty());
655 // Fail to download control types. It's believed that there is a server bug
656 // which can allow this to happen (crbug.com/164288). The sync backend host
657 // should detect this condition and fail to initialize the backend.
659 // The failure is "silent" in the sense that the GetUpdates request appears to
660 // be successful, but it returned no results. This means that the usual
661 // download retry logic will not be invoked.
662 TEST_F(SyncBackendHostTest
, SilentlyFailToDownloadControlTypes
) {
663 fake_manager_factory_
->set_configure_fail_types(syncer::ModelTypeSet::All());
664 InitializeBackend(false);
667 // Test that local refresh requests are delivered to sync.
668 TEST_F(SyncBackendHostTest
, ForwardLocalRefreshRequest
) {
669 InitializeBackend(true);
671 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
672 IssueRefreshRequest(set1
);
673 fake_manager_
->WaitForSyncThread();
674 EXPECT_TRUE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
676 syncer::ModelTypeSet set2
= syncer::ModelTypeSet(syncer::SESSIONS
);
677 IssueRefreshRequest(set2
);
678 fake_manager_
->WaitForSyncThread();
679 EXPECT_TRUE(set2
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
682 // Test that local invalidations issued before sync is initialized are ignored.
683 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestEarly
) {
684 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
685 IssueRefreshRequest(set1
);
687 InitializeBackend(true);
689 fake_manager_
->WaitForSyncThread();
690 EXPECT_FALSE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
693 // Test that local invalidations issued while sync is shutting down are ignored.
694 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestLate
) {
695 InitializeBackend(true);
697 backend_
->StopSyncingForShutdown();
699 syncer::ModelTypeSet types
= syncer::ModelTypeSet::All();
700 IssueRefreshRequest(types
);
701 fake_manager_
->WaitForSyncThread();
702 EXPECT_FALSE(types
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
704 backend_
->Shutdown(syncer::STOP_SYNC
);
708 // Test that configuration on signin sends the proper GU source.
709 TEST_F(SyncBackendHostTest
, DownloadControlTypesNewClient
) {
710 InitializeBackend(true);
711 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT
,
712 fake_manager_
->GetAndResetConfigureReason());
715 // Test that configuration on restart sends the proper GU source.
716 TEST_F(SyncBackendHostTest
, DownloadControlTypesRestart
) {
717 sync_prefs_
->SetSyncSetupCompleted();
718 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
719 fake_manager_factory_
->set_initial_sync_ended_types(enabled_types_
);
720 InitializeBackend(true);
721 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE
,
722 fake_manager_
->GetAndResetConfigureReason());
725 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
726 // setup hasn't been completed. This test ensures that cleanup happens.
727 TEST_F(SyncBackendHostTest
, TestStartupWithOldSyncData
) {
728 const char* nonsense
= "slon";
729 base::FilePath temp_directory
=
730 profile_
->GetPath().Append(base::FilePath(kTestSyncDir
));
731 base::FilePath sync_file
= temp_directory
.AppendASCII("SyncData.sqlite3");
732 ASSERT_TRUE(base::CreateDirectory(temp_directory
));
733 ASSERT_NE(-1, base::WriteFile(sync_file
, nonsense
, strlen(nonsense
)));
735 InitializeBackend(true);
737 EXPECT_FALSE(base::PathExists(sync_file
));
740 // If bookmarks encounter an error that results in disabling without purging
741 // (such as when the type is unready), and then is explicitly disabled, the
742 // SyncBackendHost needs to tell the manager to purge the type, even though
743 // it's already disabled (crbug.com/386778).
744 TEST_F(SyncBackendHostTest
, DisableThenPurgeType
) {
745 syncer::ModelTypeSet
error_types(syncer::BOOKMARKS
);
747 InitializeBackend(true);
749 // First enable the types.
750 ConfigureDataTypes(enabled_types_
,
751 Difference(syncer::ModelTypeSet::All(),
753 syncer::ModelTypeSet());
755 // Then mark the error types as unready (disables without purging).
756 ConfigureDataTypes(enabled_types_
,
757 Difference(syncer::ModelTypeSet::All(),
760 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
761 error_types
).Empty());
763 // Lastly explicitly disable the error types, which should result in a purge.
764 enabled_types_
.RemoveAll(error_types
);
765 ConfigureDataTypes(enabled_types_
,
766 Difference(syncer::ModelTypeSet::All(),
768 syncer::ModelTypeSet());
769 EXPECT_FALSE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
770 error_types
).Empty());
775 } // namespace browser_sync