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/browser/sync/glue/device_info.h"
19 #include "chrome/browser/sync/glue/synced_device_tracker.h"
20 #include "chrome/test/base/testing_browser_process.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "chrome/test/base/testing_profile_manager.h"
23 #include "components/invalidation/invalidator_state.h"
24 #include "components/invalidation/invalidator_storage.h"
25 #include "components/invalidation/profile_invalidation_provider.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/util/test_unrecoverable_error_handler.h"
47 #include "testing/gmock/include/gmock/gmock.h"
48 #include "testing/gtest/include/gtest/gtest.h"
51 using content::BrowserThread
;
52 using syncer::FakeSyncManager
;
53 using syncer::SyncManager
;
54 using ::testing::InvokeWithoutArgs
;
55 using ::testing::StrictMock
;
58 namespace browser_sync
{
62 const char kTestProfileName
[] = "test-profile";
64 static const base::FilePath::CharType kTestSyncDir
[] =
65 FILE_PATH_LITERAL("sync-test");
67 ACTION_P(Signal
, event
) {
71 void QuitMessageLoop() {
72 base::MessageLoop::current()->Quit();
75 class MockSyncFrontend
: public sync_driver::SyncFrontend
{
77 virtual ~MockSyncFrontend() {}
81 void(const syncer::WeakHandle
<syncer::JsBackend
>&,
82 const syncer::WeakHandle
<syncer::DataTypeDebugInfoListener
>&,
85 MOCK_METHOD0(OnSyncCycleCompleted
, void());
86 MOCK_METHOD1(OnConnectionStatusChange
,
87 void(syncer::ConnectionStatus status
));
88 MOCK_METHOD0(OnClearServerDataSucceeded
, void());
89 MOCK_METHOD0(OnClearServerDataFailed
, void());
90 MOCK_METHOD2(OnPassphraseRequired
,
91 void(syncer::PassphraseRequiredReason
,
92 const sync_pb::EncryptedData
&));
93 MOCK_METHOD0(OnPassphraseAccepted
, void());
94 MOCK_METHOD2(OnEncryptedTypesChanged
,
95 void(syncer::ModelTypeSet
, bool));
96 MOCK_METHOD0(OnEncryptionComplete
, void());
97 MOCK_METHOD1(OnMigrationNeededForTypes
, void(syncer::ModelTypeSet
));
98 MOCK_METHOD1(OnProtocolEvent
, void(const syncer::ProtocolEvent
&));
99 MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated
,
100 void(syncer::ModelType
, const syncer::CommitCounters
&));
101 MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated
,
102 void(syncer::ModelType
, const syncer::UpdateCounters
&));
103 MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated
,
104 void(syncer::ModelType
, const syncer::StatusCounters
&));
105 MOCK_METHOD1(OnExperimentsChanged
,
106 void(const syncer::Experiments
&));
107 MOCK_METHOD1(OnActionableError
,
108 void(const syncer::SyncProtocolError
& sync_error
));
109 MOCK_METHOD0(OnSyncConfigureRetry
, void());
112 class FakeSyncManagerFactory
: public syncer::SyncManagerFactory
{
114 explicit FakeSyncManagerFactory(FakeSyncManager
** fake_manager
)
115 : SyncManagerFactory(NORMAL
),
116 fake_manager_(fake_manager
) {
117 *fake_manager_
= NULL
;
119 virtual ~FakeSyncManagerFactory() {}
121 // SyncManagerFactory implementation. Called on the sync thread.
122 virtual scoped_ptr
<SyncManager
> CreateSyncManager(
123 std::string name
) OVERRIDE
{
124 *fake_manager_
= new FakeSyncManager(initial_sync_ended_types_
,
125 progress_marker_types_
,
126 configure_fail_types_
);
127 return scoped_ptr
<SyncManager
>(*fake_manager_
);
130 void set_initial_sync_ended_types(syncer::ModelTypeSet types
) {
131 initial_sync_ended_types_
= types
;
134 void set_progress_marker_types(syncer::ModelTypeSet types
) {
135 progress_marker_types_
= types
;
138 void set_configure_fail_types(syncer::ModelTypeSet types
) {
139 configure_fail_types_
= types
;
143 syncer::ModelTypeSet initial_sync_ended_types_
;
144 syncer::ModelTypeSet progress_marker_types_
;
145 syncer::ModelTypeSet configure_fail_types_
;
146 FakeSyncManager
** fake_manager_
;
149 class SyncBackendHostTest
: public testing::Test
{
151 SyncBackendHostTest()
152 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD
),
153 profile_manager_(TestingBrowserProcess::GetGlobal()),
154 fake_manager_(NULL
) {}
156 virtual ~SyncBackendHostTest() {}
158 virtual void SetUp() OVERRIDE
{
159 ASSERT_TRUE(profile_manager_
.SetUp());
160 profile_
= profile_manager_
.CreateTestingProfile(kTestProfileName
);
161 sync_prefs_
.reset(new sync_driver::SyncPrefs(profile_
->GetPrefs()));
162 backend_
.reset(new SyncBackendHostImpl(
163 profile_
->GetDebugName(),
165 invalidation::ProfileInvalidationProviderFactory::GetForProfile(
166 profile_
)->GetInvalidationService(),
167 sync_prefs_
->AsWeakPtr(),
168 base::FilePath(kTestSyncDir
)));
169 credentials_
.email
= "user@example.com";
170 credentials_
.sync_token
= "sync_token";
171 credentials_
.scope_set
.insert(GaiaConstants::kChromeSyncOAuth2Scope
);
173 fake_manager_factory_
.reset(new FakeSyncManagerFactory(&fake_manager_
));
175 // These types are always implicitly enabled.
176 enabled_types_
.PutAll(syncer::ControlTypes());
178 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
179 // Registrar removing them if it can't find their model workers.
180 enabled_types_
.Put(syncer::BOOKMARKS
);
181 enabled_types_
.Put(syncer::NIGORI
);
182 enabled_types_
.Put(syncer::DEVICE_INFO
);
183 enabled_types_
.Put(syncer::PREFERENCES
);
184 enabled_types_
.Put(syncer::SESSIONS
);
185 enabled_types_
.Put(syncer::SEARCH_ENGINES
);
186 enabled_types_
.Put(syncer::AUTOFILL
);
187 enabled_types_
.Put(syncer::EXPERIMENTS
);
189 network_resources_
.reset(new syncer::HttpBridgeNetworkResources());
192 virtual 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
>(),
220 fake_manager_factory_
.PassAs
<syncer::SyncManagerFactory
>(),
221 scoped_ptr
<syncer::UnrecoverableErrorHandler
>(
222 new syncer::TestUnrecoverableErrorHandler
).Pass(),
224 network_resources_
.get());
225 base::RunLoop run_loop
;
226 BrowserThread::PostDelayedTask(BrowserThread::UI
, FROM_HERE
,
227 run_loop
.QuitClosure(),
228 TestTimeouts::action_timeout());
230 // |fake_manager_factory_|'s fake_manager() is set on the sync
231 // thread, but we can rely on the message loop barriers to
232 // guarantee that we see the updated value.
233 DCHECK(fake_manager_
);
236 // Synchronously configures the backend's datatypes.
237 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add
,
238 syncer::ModelTypeSet types_to_remove
,
239 syncer::ModelTypeSet types_to_unapply
) {
240 sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap
242 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
243 sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE
,
246 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
247 sync_driver::BackendDataTypeConfigurer::DISABLED
,
248 types_to_remove
, &config_state_map
);
249 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
250 sync_driver::BackendDataTypeConfigurer::UNREADY
,
251 types_to_unapply
, &config_state_map
);
253 types_to_add
.PutAll(syncer::ControlTypes());
254 backend_
->ConfigureDataTypes(
255 syncer::CONFIGURE_REASON_RECONFIGURATION
,
257 base::Bind(&SyncBackendHostTest::DownloadReady
,
258 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());
268 void IssueRefreshRequest(syncer::ModelTypeSet types
) {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
271 content::NotificationService::current()->Notify(
272 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL
,
273 content::Source
<Profile
>(profile_
),
274 content::Details
<syncer::ModelTypeSet
>(&types
));
278 void DownloadReady(syncer::ModelTypeSet succeeded_types
,
279 syncer::ModelTypeSet failed_types
) {
280 base::MessageLoop::current()->Quit();
283 void OnDownloadRetry() {
287 content::TestBrowserThreadBundle thread_bundle_
;
288 StrictMock
<MockSyncFrontend
> mock_frontend_
;
289 syncer::SyncCredentials credentials_
;
290 TestingProfileManager profile_manager_
;
291 TestingProfile
* profile_
;
292 scoped_ptr
<sync_driver::SyncPrefs
> sync_prefs_
;
293 scoped_ptr
<SyncBackendHost
> backend_
;
294 scoped_ptr
<FakeSyncManagerFactory
> fake_manager_factory_
;
295 FakeSyncManager
* fake_manager_
;
296 syncer::ModelTypeSet enabled_types_
;
297 scoped_ptr
<syncer::NetworkResources
> network_resources_
;
300 // Test basic initialization with no initial types (first time initialization).
301 // Only the nigori should be configured.
302 TEST_F(SyncBackendHostTest
, InitShutdown
) {
303 InitializeBackend(true);
304 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
305 syncer::ControlTypes()));
306 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
307 syncer::ControlTypes()));
308 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
309 syncer::ControlTypes()).Empty());
312 // Test first time sync scenario. All types should be properly configured.
313 TEST_F(SyncBackendHostTest
, FirstTimeSync
) {
314 InitializeBackend(true);
315 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
316 syncer::ControlTypes()));
317 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
318 syncer::ControlTypes()));
319 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
320 syncer::ControlTypes()).Empty());
322 ConfigureDataTypes(enabled_types_
,
323 Difference(syncer::ModelTypeSet::All(),
325 syncer::ModelTypeSet());
326 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
327 Difference(enabled_types_
, syncer::ControlTypes())));
328 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
329 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
330 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
331 enabled_types_
).Empty());
334 // Test the restart after setting up sync scenario. No enabled types should be
335 // downloaded or cleaned.
336 TEST_F(SyncBackendHostTest
, Restart
) {
337 sync_prefs_
->SetSyncSetupCompleted();
338 syncer::ModelTypeSet all_but_nigori
= enabled_types_
;
339 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
340 fake_manager_factory_
->set_initial_sync_ended_types(enabled_types_
);
341 InitializeBackend(true);
342 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
343 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
344 enabled_types_
).Empty());
345 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
346 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
347 enabled_types_
).Empty());
349 ConfigureDataTypes(enabled_types_
,
350 Difference(syncer::ModelTypeSet::All(),
352 syncer::ModelTypeSet());
353 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
354 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
355 enabled_types_
).Empty());
356 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
357 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
358 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
359 enabled_types_
).Empty());
362 // Test a sync restart scenario where some types had never finished configuring.
363 // The partial types should be purged, then reconfigured properly.
364 TEST_F(SyncBackendHostTest
, PartialTypes
) {
365 sync_prefs_
->SetSyncSetupCompleted();
366 // Set sync manager behavior before passing it down. All types have progress
367 // markers, but nigori and bookmarks are missing initial sync ended.
368 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
369 syncer::ModelTypeSet full_types
=
370 Difference(enabled_types_
, partial_types
);
371 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
372 fake_manager_factory_
->set_initial_sync_ended_types(full_types
);
374 // Bringing up the backend should purge all partial types, then proceed to
375 // download the Nigori.
376 InitializeBackend(true);
377 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
378 syncer::ModelTypeSet(syncer::NIGORI
)));
379 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
380 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
381 Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
382 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
383 enabled_types_
).Equals(
384 Difference(partial_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
386 // Now do the actual configuration, which should download and apply bookmarks.
387 ConfigureDataTypes(enabled_types_
,
388 Difference(syncer::ModelTypeSet::All(),
390 syncer::ModelTypeSet());
391 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
392 enabled_types_
).Empty());
393 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
395 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
396 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
397 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
398 enabled_types_
).Empty());
401 // Test the behavior when we lose the sync db. Although we already have types
402 // enabled, we should re-download all of them because we lost their data.
403 TEST_F(SyncBackendHostTest
, LostDB
) {
404 sync_prefs_
->SetSyncSetupCompleted();
405 // Initialization should fetch the Nigori node. Everything else should be
407 InitializeBackend(true);
408 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
409 syncer::ModelTypeSet(syncer::ControlTypes())));
410 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
411 syncer::ModelTypeSet(syncer::ControlTypes())));
412 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
413 enabled_types_
).Equals(
414 Difference(enabled_types_
, syncer::ControlTypes())));
416 // The database was empty, so any cleaning is entirely optional. We want to
417 // reset this value before running the next part of the test, though.
418 fake_manager_
->GetAndResetCleanedTypes();
420 // The actual configuration should redownload and apply all the enabled types.
421 ConfigureDataTypes(enabled_types_
,
422 Difference(syncer::ModelTypeSet::All(),
424 syncer::ModelTypeSet());
425 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().HasAll(
426 Difference(enabled_types_
, syncer::ControlTypes())));
427 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
428 enabled_types_
).Empty());
429 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
430 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
431 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
432 enabled_types_
).Empty());
435 TEST_F(SyncBackendHostTest
, DisableTypes
) {
436 // Simulate first time sync.
437 InitializeBackend(true);
438 fake_manager_
->GetAndResetCleanedTypes();
439 ConfigureDataTypes(enabled_types_
,
440 Difference(syncer::ModelTypeSet::All(),
442 syncer::ModelTypeSet());
443 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
445 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
446 enabled_types_
).Empty());
447 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
448 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
449 enabled_types_
).Empty());
451 // Then disable two datatypes.
452 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
453 syncer::SEARCH_ENGINES
);
454 syncer::ModelTypeSet old_types
= enabled_types_
;
455 enabled_types_
.RemoveAll(disabled_types
);
456 ConfigureDataTypes(enabled_types_
,
457 Difference(syncer::ModelTypeSet::All(),
459 syncer::ModelTypeSet());
461 // Only those datatypes disabled should be cleaned. Nothing should be
463 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
464 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
465 old_types
).Equals(disabled_types
));
466 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
467 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
468 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
469 enabled_types_
).Empty());
472 TEST_F(SyncBackendHostTest
, AddTypes
) {
473 // Simulate first time sync.
474 InitializeBackend(true);
475 fake_manager_
->GetAndResetCleanedTypes();
476 ConfigureDataTypes(enabled_types_
,
477 Difference(syncer::ModelTypeSet::All(),
479 syncer::ModelTypeSet());
480 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
482 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
483 enabled_types_
).Empty());
484 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
485 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
486 enabled_types_
).Empty());
488 // Then add two datatypes.
489 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
491 enabled_types_
.PutAll(new_types
);
492 ConfigureDataTypes(enabled_types_
,
493 Difference(syncer::ModelTypeSet::All(),
495 syncer::ModelTypeSet());
497 // Only those datatypes added should be downloaded (plus nigori). Nothing
498 // should be cleaned aside from the disabled types.
499 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
500 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
501 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
502 enabled_types_
).Empty());
503 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
504 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
505 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
506 enabled_types_
).Empty());
509 // And and disable in the same configuration.
510 TEST_F(SyncBackendHostTest
, AddDisableTypes
) {
511 // Simulate first time sync.
512 InitializeBackend(true);
513 fake_manager_
->GetAndResetCleanedTypes();
514 ConfigureDataTypes(enabled_types_
,
515 Difference(syncer::ModelTypeSet::All(),
517 syncer::ModelTypeSet());
518 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
520 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
521 enabled_types_
).Empty());
522 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
523 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
524 enabled_types_
).Empty());
526 // Then add two datatypes.
527 syncer::ModelTypeSet old_types
= enabled_types_
;
528 syncer::ModelTypeSet
disabled_types(syncer::BOOKMARKS
,
529 syncer::SEARCH_ENGINES
);
530 syncer::ModelTypeSet
new_types(syncer::EXTENSIONS
,
532 enabled_types_
.PutAll(new_types
);
533 enabled_types_
.RemoveAll(disabled_types
);
534 ConfigureDataTypes(enabled_types_
,
535 Difference(syncer::ModelTypeSet::All(),
537 syncer::ModelTypeSet());
539 // Only those datatypes added should be downloaded (plus nigori). Nothing
540 // should be cleaned aside from the disabled types.
541 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
542 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
543 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
544 old_types
).Equals(disabled_types
));
545 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
546 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
547 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
548 old_types
).Equals(disabled_types
));
551 // Test restarting the browser to newly supported datatypes. The new datatypes
552 // should be downloaded on the configuration after backend initialization.
553 TEST_F(SyncBackendHostTest
, NewlySupportedTypes
) {
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 fake_manager_factory_
->set_progress_marker_types(old_types
);
559 fake_manager_factory_
->set_initial_sync_ended_types(old_types
);
560 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
561 syncer::EXTENSION_SETTINGS
);
562 enabled_types_
.PutAll(new_types
);
565 InitializeBackend(true);
566 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Empty());
567 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
569 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(old_types
));
570 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
571 enabled_types_
).Equals(new_types
));
573 // Downloads and applies the new types.
574 ConfigureDataTypes(enabled_types_
,
575 Difference(syncer::ModelTypeSet::All(),
577 syncer::ModelTypeSet());
578 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
579 Union(new_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
580 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
581 enabled_types_
).Empty());
582 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
583 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
584 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
585 enabled_types_
).Empty());
588 // Test the newly supported types scenario, but with the presence of partial
589 // types as well. Both partial and newly supported types should be downloaded
590 // the configuration.
591 TEST_F(SyncBackendHostTest
, NewlySupportedTypesWithPartialTypes
) {
592 sync_prefs_
->SetSyncSetupCompleted();
593 // Set sync manager behavior before passing it down. All types have progress
594 // markers and initial sync ended except the new types.
595 syncer::ModelTypeSet old_types
= enabled_types_
;
596 syncer::ModelTypeSet
partial_types(syncer::NIGORI
, syncer::BOOKMARKS
);
597 syncer::ModelTypeSet full_types
=
598 Difference(enabled_types_
, partial_types
);
599 fake_manager_factory_
->set_progress_marker_types(old_types
);
600 fake_manager_factory_
->set_initial_sync_ended_types(full_types
);
601 syncer::ModelTypeSet
new_types(syncer::APP_SETTINGS
,
602 syncer::EXTENSION_SETTINGS
);
603 enabled_types_
.PutAll(new_types
);
605 // Purge the partial types. The nigori will be among the purged types, but
606 // the syncer will re-download it by the time the initialization is complete.
607 InitializeBackend(true);
608 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
609 syncer::ModelTypeSet(syncer::NIGORI
)));
610 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().HasAll(partial_types
));
611 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(
612 syncer::Union(full_types
, syncer::ModelTypeSet(syncer::NIGORI
))));
613 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
614 enabled_types_
).Equals(Union(new_types
, Difference(
615 partial_types
, syncer::ModelTypeSet(syncer::NIGORI
)))));
617 // Downloads and applies the new types and partial types (which includes
619 ConfigureDataTypes(enabled_types_
,
620 Difference(syncer::ModelTypeSet::All(),
622 syncer::ModelTypeSet());
623 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(
624 Union(new_types
, partial_types
)));
625 EXPECT_TRUE(Intersection(fake_manager_
->GetAndResetCleanedTypes(),
626 enabled_types_
).Empty());
627 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
628 EXPECT_TRUE(fake_manager_
->GetAndResetEnabledTypes().Equals(enabled_types_
));
629 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
630 enabled_types_
).Empty());
633 // Ensure the device info tracker is initialized properly on startup.
634 TEST_F(SyncBackendHostTest
, InitializeDeviceInfo
) {
635 ASSERT_EQ(NULL
, backend_
->GetSyncedDeviceTracker());
637 InitializeBackend(true);
638 const SyncedDeviceTracker
* device_tracker
=
639 backend_
->GetSyncedDeviceTracker();
640 ASSERT_TRUE(device_tracker
->ReadLocalDeviceInfo());
643 // Verify that downloading control types only downloads those types that do
644 // not have initial sync ended set.
645 TEST_F(SyncBackendHostTest
, DownloadControlTypes
) {
646 sync_prefs_
->SetSyncSetupCompleted();
647 // Set sync manager behavior before passing it down. Experiments and device
648 // info are new types without progress markers or initial sync ended, while
649 // all other types have been fully downloaded and applied.
650 syncer::ModelTypeSet
new_types(syncer::EXPERIMENTS
, syncer::DEVICE_INFO
);
651 syncer::ModelTypeSet old_types
=
652 Difference(enabled_types_
, new_types
);
653 fake_manager_factory_
->set_progress_marker_types(old_types
);
654 fake_manager_factory_
->set_initial_sync_ended_types(old_types
);
656 // Bringing up the backend should download the new types without downloading
658 InitializeBackend(true);
659 EXPECT_TRUE(fake_manager_
->GetAndResetDownloadedTypes().Equals(new_types
));
660 EXPECT_TRUE(fake_manager_
->GetAndResetCleanedTypes().Equals(
661 Difference(syncer::ModelTypeSet::All(),
663 EXPECT_TRUE(fake_manager_
->InitialSyncEndedTypes().Equals(enabled_types_
));
664 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
665 enabled_types_
).Empty());
668 // Fail to download control types. It's believed that there is a server bug
669 // which can allow this to happen (crbug.com/164288). The sync backend host
670 // should detect this condition and fail to initialize the backend.
672 // The failure is "silent" in the sense that the GetUpdates request appears to
673 // be successful, but it returned no results. This means that the usual
674 // download retry logic will not be invoked.
675 TEST_F(SyncBackendHostTest
, SilentlyFailToDownloadControlTypes
) {
676 fake_manager_factory_
->set_configure_fail_types(syncer::ModelTypeSet::All());
677 InitializeBackend(false);
680 // Test that local refresh requests are delivered to sync.
681 TEST_F(SyncBackendHostTest
, ForwardLocalRefreshRequest
) {
682 InitializeBackend(true);
684 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
685 IssueRefreshRequest(set1
);
686 fake_manager_
->WaitForSyncThread();
687 EXPECT_TRUE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
689 syncer::ModelTypeSet set2
= syncer::ModelTypeSet(syncer::SESSIONS
);
690 IssueRefreshRequest(set2
);
691 fake_manager_
->WaitForSyncThread();
692 EXPECT_TRUE(set2
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
695 // Test that local invalidations issued before sync is initialized are ignored.
696 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestEarly
) {
697 syncer::ModelTypeSet set1
= syncer::ModelTypeSet::All();
698 IssueRefreshRequest(set1
);
700 InitializeBackend(true);
702 fake_manager_
->WaitForSyncThread();
703 EXPECT_FALSE(set1
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
706 // Test that local invalidations issued while sync is shutting down are ignored.
707 TEST_F(SyncBackendHostTest
, AttemptForwardLocalRefreshRequestLate
) {
708 InitializeBackend(true);
710 backend_
->StopSyncingForShutdown();
712 syncer::ModelTypeSet types
= syncer::ModelTypeSet::All();
713 IssueRefreshRequest(types
);
714 fake_manager_
->WaitForSyncThread();
715 EXPECT_FALSE(types
.Equals(fake_manager_
->GetLastRefreshRequestTypes()));
717 backend_
->Shutdown(syncer::STOP_SYNC
);
721 // Test that configuration on signin sends the proper GU source.
722 TEST_F(SyncBackendHostTest
, DownloadControlTypesNewClient
) {
723 InitializeBackend(true);
724 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT
,
725 fake_manager_
->GetAndResetConfigureReason());
728 // Test that configuration on restart sends the proper GU source.
729 TEST_F(SyncBackendHostTest
, DownloadControlTypesRestart
) {
730 sync_prefs_
->SetSyncSetupCompleted();
731 fake_manager_factory_
->set_progress_marker_types(enabled_types_
);
732 fake_manager_factory_
->set_initial_sync_ended_types(enabled_types_
);
733 InitializeBackend(true);
734 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE
,
735 fake_manager_
->GetAndResetConfigureReason());
738 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
739 // setup hasn't been completed. This test ensures that cleanup happens.
740 TEST_F(SyncBackendHostTest
, TestStartupWithOldSyncData
) {
741 const char* nonsense
= "slon";
742 base::FilePath temp_directory
=
743 profile_
->GetPath().Append(base::FilePath(kTestSyncDir
));
744 base::FilePath sync_file
= temp_directory
.AppendASCII("SyncData.sqlite3");
745 ASSERT_TRUE(base::CreateDirectory(temp_directory
));
746 ASSERT_NE(-1, base::WriteFile(sync_file
, nonsense
, strlen(nonsense
)));
748 InitializeBackend(true);
750 EXPECT_FALSE(base::PathExists(sync_file
));
753 // If bookmarks encounter an error that results in disabling without purging
754 // (such as when the type is unready), and then is explicitly disabled, the
755 // SyncBackendHost needs to tell the manager to purge the type, even though
756 // it's already disabled (crbug.com/386778).
757 TEST_F(SyncBackendHostTest
, DisableThenPurgeType
) {
758 syncer::ModelTypeSet
error_types(syncer::BOOKMARKS
);
760 InitializeBackend(true);
762 // First enable the types.
763 ConfigureDataTypes(enabled_types_
,
764 Difference(syncer::ModelTypeSet::All(),
766 syncer::ModelTypeSet());
768 // Then mark the error types as unready (disables without purging).
769 ConfigureDataTypes(enabled_types_
,
770 Difference(syncer::ModelTypeSet::All(),
773 EXPECT_TRUE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
774 error_types
).Empty());
776 // Lastly explicitly disable the error types, which should result in a purge.
777 enabled_types_
.RemoveAll(error_types
);
778 ConfigureDataTypes(enabled_types_
,
779 Difference(syncer::ModelTypeSet::All(),
781 syncer::ModelTypeSet());
782 EXPECT_FALSE(fake_manager_
->GetTypesWithEmptyProgressMarkerToken(
783 error_types
).Empty());
788 } // namespace browser_sync