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/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_storage.h"
24 #include "components/invalidation/profile_invalidation_provider.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 "net/url_request/test_url_fetcher_factory.h"
32 #include "sync/internal_api/public/base/invalidator_state.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 SyncFrontend {
76 virtual ~MockSyncFrontend() {}
80 void(const syncer::WeakHandle<syncer::JsBackend>&,
81 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&,
83 MOCK_METHOD0(OnSyncCycleCompleted, void());
84 MOCK_METHOD1(OnConnectionStatusChange,
85 void(syncer::ConnectionStatus status));
86 MOCK_METHOD0(OnClearServerDataSucceeded, void());
87 MOCK_METHOD0(OnClearServerDataFailed, void());
88 MOCK_METHOD2(OnPassphraseRequired,
89 void(syncer::PassphraseRequiredReason,
90 const sync_pb::EncryptedData&));
91 MOCK_METHOD0(OnPassphraseAccepted, void());
92 MOCK_METHOD2(OnEncryptedTypesChanged,
93 void(syncer::ModelTypeSet, bool));
94 MOCK_METHOD0(OnEncryptionComplete, void());
95 MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet));
96 MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&));
97 MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated,
98 void(syncer::ModelType, const syncer::CommitCounters&));
99 MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated,
100 void(syncer::ModelType, const syncer::UpdateCounters&));
101 MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated,
102 void(syncer::ModelType, const syncer::StatusCounters&));
103 MOCK_METHOD1(OnExperimentsChanged,
104 void(const syncer::Experiments&));
105 MOCK_METHOD1(OnActionableError,
106 void(const syncer::SyncProtocolError& sync_error));
107 MOCK_METHOD0(OnSyncConfigureRetry, void());
110 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
112 explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager)
113 : SyncManagerFactory(NORMAL),
114 fake_manager_(fake_manager) {
115 *fake_manager_ = NULL;
117 virtual ~FakeSyncManagerFactory() {}
119 // SyncManagerFactory implementation. Called on the sync thread.
120 virtual scoped_ptr<SyncManager> CreateSyncManager(
121 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";
170 fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
172 // These types are always implicitly enabled.
173 enabled_types_.PutAll(syncer::ControlTypes());
175 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
176 // Registrar removing them if it can't find their model workers.
177 enabled_types_.Put(syncer::BOOKMARKS);
178 enabled_types_.Put(syncer::NIGORI);
179 enabled_types_.Put(syncer::DEVICE_INFO);
180 enabled_types_.Put(syncer::PREFERENCES);
181 enabled_types_.Put(syncer::SESSIONS);
182 enabled_types_.Put(syncer::SEARCH_ENGINES);
183 enabled_types_.Put(syncer::AUTOFILL);
184 enabled_types_.Put(syncer::EXPERIMENTS);
186 network_resources_.reset(new syncer::HttpBridgeNetworkResources());
189 virtual void TearDown() OVERRIDE {
191 backend_->StopSyncingForShutdown();
192 backend_->Shutdown(SyncBackendHost::STOP);
197 profile_manager_.DeleteTestingProfile(kTestProfileName);
198 // Pump messages posted by the sync thread (which may end up
199 // posting on the IO thread).
200 base::RunLoop().RunUntilIdle();
201 content::RunAllPendingInMessageLoop(BrowserThread::IO);
202 // Pump any messages posted by the IO thread.
203 base::RunLoop().RunUntilIdle();
206 // Synchronously initializes the backend.
207 void InitializeBackend(bool expect_success) {
208 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, expect_success)).
209 WillOnce(InvokeWithoutArgs(QuitMessageLoop));
210 backend_->Initialize(
212 scoped_ptr<base::Thread>(),
213 syncer::WeakHandle<syncer::JsEventHandler>(),
217 fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
218 scoped_ptr<syncer::UnrecoverableErrorHandler>(
219 new syncer::TestUnrecoverableErrorHandler).Pass(),
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 BackendDataTypeConfigurer::DataTypeConfigStateMap config_state_map;
237 BackendDataTypeConfigurer::SetDataTypesState(
238 BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
241 BackendDataTypeConfigurer::SetDataTypesState(
242 BackendDataTypeConfigurer::DISABLED,
243 types_to_remove, &config_state_map);
245 types_to_add.PutAll(syncer::ControlTypes());
246 backend_->ConfigureDataTypes(
247 syncer::CONFIGURE_REASON_RECONFIGURATION,
249 base::Bind(&SyncBackendHostTest::DownloadReady,
250 base::Unretained(this)),
251 base::Bind(&SyncBackendHostTest::OnDownloadRetry,
252 base::Unretained(this)));
253 base::RunLoop run_loop;
254 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
255 run_loop.QuitClosure(),
256 TestTimeouts::action_timeout());
260 void IssueRefreshRequest(syncer::ModelTypeSet types) {
261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
263 content::NotificationService::current()->Notify(
264 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
265 content::Source<Profile>(profile_),
266 content::Details<syncer::ModelTypeSet>(&types));
270 void DownloadReady(syncer::ModelTypeSet succeeded_types,
271 syncer::ModelTypeSet failed_types) {
272 base::MessageLoop::current()->Quit();
275 void OnDownloadRetry() {
279 content::TestBrowserThreadBundle thread_bundle_;
280 StrictMock<MockSyncFrontend> mock_frontend_;
281 syncer::SyncCredentials credentials_;
282 TestingProfileManager profile_manager_;
283 TestingProfile* profile_;
284 scoped_ptr<sync_driver::SyncPrefs> sync_prefs_;
285 scoped_ptr<SyncBackendHost> backend_;
286 scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
287 FakeSyncManager* fake_manager_;
288 syncer::ModelTypeSet enabled_types_;
289 scoped_ptr<syncer::NetworkResources> network_resources_;
292 // Test basic initialization with no initial types (first time initialization).
293 // Only the nigori should be configured.
294 TEST_F(SyncBackendHostTest, InitShutdown) {
295 InitializeBackend(true);
296 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
297 syncer::ControlTypes()));
298 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
299 syncer::ControlTypes()));
300 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
301 syncer::ControlTypes()).Empty());
304 // Test first time sync scenario. All types should be properly configured.
305 TEST_F(SyncBackendHostTest, FirstTimeSync) {
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());
314 ConfigureDataTypes(enabled_types_,
315 Difference(syncer::ModelTypeSet::All(),
317 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
318 Difference(enabled_types_, syncer::ControlTypes())));
319 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
320 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
321 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
322 enabled_types_).Empty());
325 // Test the restart after setting up sync scenario. No enabled types should be
326 // downloaded or cleaned.
327 TEST_F(SyncBackendHostTest, Restart) {
328 sync_prefs_->SetSyncSetupCompleted();
329 syncer::ModelTypeSet all_but_nigori = enabled_types_;
330 fake_manager_factory_->set_progress_marker_types(enabled_types_);
331 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
332 InitializeBackend(true);
333 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
334 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
335 enabled_types_).Empty());
336 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
337 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
338 enabled_types_).Empty());
340 ConfigureDataTypes(enabled_types_,
341 Difference(syncer::ModelTypeSet::All(),
343 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
344 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
345 enabled_types_).Empty());
346 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
347 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
348 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
349 enabled_types_).Empty());
352 // Test a sync restart scenario where some types had never finished configuring.
353 // The partial types should be purged, then reconfigured properly.
354 TEST_F(SyncBackendHostTest, PartialTypes) {
355 sync_prefs_->SetSyncSetupCompleted();
356 // Set sync manager behavior before passing it down. All types have progress
357 // markers, but nigori and bookmarks are missing initial sync ended.
358 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
359 syncer::ModelTypeSet full_types =
360 Difference(enabled_types_, partial_types);
361 fake_manager_factory_->set_progress_marker_types(enabled_types_);
362 fake_manager_factory_->set_initial_sync_ended_types(full_types);
364 // Bringing up the backend should purge all partial types, then proceed to
365 // download the Nigori.
366 InitializeBackend(true);
367 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
368 syncer::ModelTypeSet(syncer::NIGORI)));
369 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
370 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
371 Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
372 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
373 enabled_types_).Equals(
374 Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
376 // Now do the actual configuration, which should download and apply bookmarks.
377 ConfigureDataTypes(enabled_types_,
378 Difference(syncer::ModelTypeSet::All(),
380 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
381 enabled_types_).Empty());
382 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
384 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
385 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
386 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
387 enabled_types_).Empty());
390 // Test the behavior when we lose the sync db. Although we already have types
391 // enabled, we should re-download all of them because we lost their data.
392 TEST_F(SyncBackendHostTest, LostDB) {
393 sync_prefs_->SetSyncSetupCompleted();
394 // Initialization should fetch the Nigori node. Everything else should be
396 InitializeBackend(true);
397 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
398 syncer::ModelTypeSet(syncer::ControlTypes())));
399 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
400 syncer::ModelTypeSet(syncer::ControlTypes())));
401 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
402 enabled_types_).Equals(
403 Difference(enabled_types_, syncer::ControlTypes())));
405 // The database was empty, so any cleaning is entirely optional. We want to
406 // reset this value before running the next part of the test, though.
407 fake_manager_->GetAndResetCleanedTypes();
409 // The actual configuration should redownload and apply all the enabled types.
410 ConfigureDataTypes(enabled_types_,
411 Difference(syncer::ModelTypeSet::All(),
413 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
414 Difference(enabled_types_, syncer::ControlTypes())));
415 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
416 enabled_types_).Empty());
417 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
418 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
419 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
420 enabled_types_).Empty());
423 TEST_F(SyncBackendHostTest, DisableTypes) {
424 // Simulate first time sync.
425 InitializeBackend(true);
426 fake_manager_->GetAndResetCleanedTypes();
427 ConfigureDataTypes(enabled_types_,
428 Difference(syncer::ModelTypeSet::All(),
430 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
432 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
433 enabled_types_).Empty());
434 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
435 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
436 enabled_types_).Empty());
438 // Then disable two datatypes.
439 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
440 syncer::SEARCH_ENGINES);
441 syncer::ModelTypeSet old_types = enabled_types_;
442 enabled_types_.RemoveAll(disabled_types);
443 ConfigureDataTypes(enabled_types_,
444 Difference(syncer::ModelTypeSet::All(),
447 // Only those datatypes disabled should be cleaned. Nothing should be
449 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
450 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
451 old_types).Equals(disabled_types));
452 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
453 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
454 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
455 enabled_types_).Empty());
458 TEST_F(SyncBackendHostTest, AddTypes) {
459 // Simulate first time sync.
460 InitializeBackend(true);
461 fake_manager_->GetAndResetCleanedTypes();
462 ConfigureDataTypes(enabled_types_,
463 Difference(syncer::ModelTypeSet::All(),
465 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
467 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
468 enabled_types_).Empty());
469 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
470 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
471 enabled_types_).Empty());
473 // Then add two datatypes.
474 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
476 enabled_types_.PutAll(new_types);
477 ConfigureDataTypes(enabled_types_,
478 Difference(syncer::ModelTypeSet::All(),
481 // Only those datatypes added should be downloaded (plus nigori). Nothing
482 // should be cleaned aside from the disabled types.
483 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
484 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
485 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
486 enabled_types_).Empty());
487 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
488 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
489 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
490 enabled_types_).Empty());
493 // And and disable in the same configuration.
494 TEST_F(SyncBackendHostTest, AddDisableTypes) {
495 // Simulate first time sync.
496 InitializeBackend(true);
497 fake_manager_->GetAndResetCleanedTypes();
498 ConfigureDataTypes(enabled_types_,
499 Difference(syncer::ModelTypeSet::All(),
501 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
503 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
504 enabled_types_).Empty());
505 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
506 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
507 enabled_types_).Empty());
509 // Then add two datatypes.
510 syncer::ModelTypeSet old_types = enabled_types_;
511 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
512 syncer::SEARCH_ENGINES);
513 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
515 enabled_types_.PutAll(new_types);
516 enabled_types_.RemoveAll(disabled_types);
517 ConfigureDataTypes(enabled_types_,
518 Difference(syncer::ModelTypeSet::All(),
521 // Only those datatypes added should be downloaded (plus nigori). Nothing
522 // should be cleaned aside from the disabled types.
523 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
524 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
525 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
526 old_types).Equals(disabled_types));
527 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
528 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
529 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
530 old_types).Equals(disabled_types));
533 // Test restarting the browser to newly supported datatypes. The new datatypes
534 // should be downloaded on the configuration after backend initialization.
535 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
536 sync_prefs_->SetSyncSetupCompleted();
537 // Set sync manager behavior before passing it down. All types have progress
538 // markers and initial sync ended except the new types.
539 syncer::ModelTypeSet old_types = enabled_types_;
540 fake_manager_factory_->set_progress_marker_types(old_types);
541 fake_manager_factory_->set_initial_sync_ended_types(old_types);
542 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
543 syncer::EXTENSION_SETTINGS);
544 enabled_types_.PutAll(new_types);
547 InitializeBackend(true);
548 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
549 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
551 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
552 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
553 enabled_types_).Equals(new_types));
555 // Downloads and applies the new types.
556 ConfigureDataTypes(enabled_types_,
557 Difference(syncer::ModelTypeSet::All(),
559 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
560 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
561 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
562 enabled_types_).Empty());
563 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
564 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
565 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
566 enabled_types_).Empty());
569 // Test the newly supported types scenario, but with the presence of partial
570 // types as well. Both partial and newly supported types should be downloaded
571 // the configuration.
572 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
573 sync_prefs_->SetSyncSetupCompleted();
574 // Set sync manager behavior before passing it down. All types have progress
575 // markers and initial sync ended except the new types.
576 syncer::ModelTypeSet old_types = enabled_types_;
577 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
578 syncer::ModelTypeSet full_types =
579 Difference(enabled_types_, partial_types);
580 fake_manager_factory_->set_progress_marker_types(old_types);
581 fake_manager_factory_->set_initial_sync_ended_types(full_types);
582 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
583 syncer::EXTENSION_SETTINGS);
584 enabled_types_.PutAll(new_types);
586 // Purge the partial types. The nigori will be among the purged types, but
587 // the syncer will re-download it by the time the initialization is complete.
588 InitializeBackend(true);
589 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
590 syncer::ModelTypeSet(syncer::NIGORI)));
591 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
592 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
593 syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
594 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
595 enabled_types_).Equals(Union(new_types, Difference(
596 partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
598 // Downloads and applies the new types and partial types (which includes
600 ConfigureDataTypes(enabled_types_,
601 Difference(syncer::ModelTypeSet::All(),
603 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
604 Union(new_types, partial_types)));
605 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
606 enabled_types_).Empty());
607 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
608 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
609 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
610 enabled_types_).Empty());
613 // Ensure the device info tracker is initialized properly on startup.
614 TEST_F(SyncBackendHostTest, InitializeDeviceInfo) {
615 ASSERT_EQ(NULL, backend_->GetSyncedDeviceTracker());
617 InitializeBackend(true);
618 const SyncedDeviceTracker* device_tracker =
619 backend_->GetSyncedDeviceTracker();
620 ASSERT_TRUE(device_tracker->ReadLocalDeviceInfo());
623 // Verify that downloading control types only downloads those types that do
624 // not have initial sync ended set.
625 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
626 sync_prefs_->SetSyncSetupCompleted();
627 // Set sync manager behavior before passing it down. Experiments and device
628 // info are new types without progress markers or initial sync ended, while
629 // all other types have been fully downloaded and applied.
630 syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::DEVICE_INFO);
631 syncer::ModelTypeSet old_types =
632 Difference(enabled_types_, new_types);
633 fake_manager_factory_->set_progress_marker_types(old_types);
634 fake_manager_factory_->set_initial_sync_ended_types(old_types);
636 // Bringing up the backend should download the new types without downloading
638 InitializeBackend(true);
639 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
640 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
641 Difference(syncer::ModelTypeSet::All(),
643 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
644 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
645 enabled_types_).Empty());
648 // Fail to download control types. It's believed that there is a server bug
649 // which can allow this to happen (crbug.com/164288). The sync backend host
650 // should detect this condition and fail to initialize the backend.
652 // The failure is "silent" in the sense that the GetUpdates request appears to
653 // be successful, but it returned no results. This means that the usual
654 // download retry logic will not be invoked.
655 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
656 fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
657 InitializeBackend(false);
660 // Test that local refresh requests are delivered to sync.
661 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
662 InitializeBackend(true);
664 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
665 IssueRefreshRequest(set1);
666 fake_manager_->WaitForSyncThread();
667 EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
669 syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
670 IssueRefreshRequest(set2);
671 fake_manager_->WaitForSyncThread();
672 EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
675 // Test that local invalidations issued before sync is initialized are ignored.
676 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
677 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
678 IssueRefreshRequest(set1);
680 InitializeBackend(true);
682 fake_manager_->WaitForSyncThread();
683 EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
686 // Test that local invalidations issued while sync is shutting down are ignored.
687 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
688 InitializeBackend(true);
690 backend_->StopSyncingForShutdown();
692 syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
693 IssueRefreshRequest(types);
694 fake_manager_->WaitForSyncThread();
695 EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
697 backend_->Shutdown(SyncBackendHost::STOP);
701 // Test that configuration on signin sends the proper GU source.
702 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
703 InitializeBackend(true);
704 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
705 fake_manager_->GetAndResetConfigureReason());
708 // Test that configuration on restart sends the proper GU source.
709 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
710 sync_prefs_->SetSyncSetupCompleted();
711 fake_manager_factory_->set_progress_marker_types(enabled_types_);
712 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
713 InitializeBackend(true);
714 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
715 fake_manager_->GetAndResetConfigureReason());
718 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
719 // setup hasn't been completed. This test ensures that cleanup happens.
720 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) {
721 const char* nonsense = "slon";
722 base::FilePath temp_directory =
723 profile_->GetPath().Append(base::FilePath(kTestSyncDir));
724 base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3");
725 ASSERT_TRUE(base::CreateDirectory(temp_directory));
726 ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense)));
728 InitializeBackend(true);
730 EXPECT_FALSE(base::PathExists(sync_file));
735 } // namespace browser_sync