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 virtual ~FakeSyncManagerFactory() {}
120 // SyncManagerFactory implementation. Called on the sync thread.
121 virtual scoped_ptr<SyncManager> CreateSyncManager(
122 std::string name) OVERRIDE {
123 *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_,
124 progress_marker_types_,
125 configure_fail_types_);
126 return scoped_ptr<SyncManager>(*fake_manager_);
129 void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
130 initial_sync_ended_types_ = types;
133 void set_progress_marker_types(syncer::ModelTypeSet types) {
134 progress_marker_types_ = types;
137 void set_configure_fail_types(syncer::ModelTypeSet types) {
138 configure_fail_types_ = types;
142 syncer::ModelTypeSet initial_sync_ended_types_;
143 syncer::ModelTypeSet progress_marker_types_;
144 syncer::ModelTypeSet configure_fail_types_;
145 FakeSyncManager** fake_manager_;
148 class SyncBackendHostTest : public testing::Test {
150 SyncBackendHostTest()
151 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
152 profile_manager_(TestingBrowserProcess::GetGlobal()),
153 fake_manager_(NULL) {}
155 virtual ~SyncBackendHostTest() {}
157 virtual void SetUp() OVERRIDE {
158 ASSERT_TRUE(profile_manager_.SetUp());
159 profile_ = profile_manager_.CreateTestingProfile(kTestProfileName);
160 sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
161 backend_.reset(new SyncBackendHostImpl(
162 profile_->GetDebugName(),
164 invalidation::ProfileInvalidationProviderFactory::GetForProfile(
165 profile_)->GetInvalidationService(),
166 sync_prefs_->AsWeakPtr(),
167 base::FilePath(kTestSyncDir)));
168 credentials_.email = "user@example.com";
169 credentials_.sync_token = "sync_token";
170 credentials_.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope);
172 fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
174 // These types are always implicitly enabled.
175 enabled_types_.PutAll(syncer::ControlTypes());
177 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
178 // Registrar removing them if it can't find their model workers.
179 enabled_types_.Put(syncer::BOOKMARKS);
180 enabled_types_.Put(syncer::NIGORI);
181 enabled_types_.Put(syncer::DEVICE_INFO);
182 enabled_types_.Put(syncer::PREFERENCES);
183 enabled_types_.Put(syncer::SESSIONS);
184 enabled_types_.Put(syncer::SEARCH_ENGINES);
185 enabled_types_.Put(syncer::AUTOFILL);
186 enabled_types_.Put(syncer::EXPERIMENTS);
188 network_resources_.reset(new syncer::HttpBridgeNetworkResources());
191 virtual void TearDown() OVERRIDE {
193 backend_->StopSyncingForShutdown();
194 backend_->Shutdown(syncer::STOP_SYNC);
199 profile_manager_.DeleteTestingProfile(kTestProfileName);
200 // Pump messages posted by the sync thread (which may end up
201 // posting on the IO thread).
202 base::RunLoop().RunUntilIdle();
203 content::RunAllPendingInMessageLoop(BrowserThread::IO);
204 // Pump any messages posted by the IO thread.
205 base::RunLoop().RunUntilIdle();
208 // Synchronously initializes the backend.
209 void InitializeBackend(bool expect_success) {
210 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, _, expect_success)).
211 WillOnce(InvokeWithoutArgs(QuitMessageLoop));
212 backend_->Initialize(
214 scoped_ptr<base::Thread>(),
215 syncer::WeakHandle<syncer::JsEventHandler>(),
219 fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
220 scoped_ptr<syncer::UnrecoverableErrorHandler>(
221 new syncer::TestUnrecoverableErrorHandler).Pass(),
223 network_resources_.get());
224 base::RunLoop run_loop;
225 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
226 run_loop.QuitClosure(),
227 TestTimeouts::action_timeout());
229 // |fake_manager_factory_|'s fake_manager() is set on the sync
230 // thread, but we can rely on the message loop barriers to
231 // guarantee that we see the updated value.
232 DCHECK(fake_manager_);
235 // Synchronously configures the backend's datatypes.
236 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add,
237 syncer::ModelTypeSet types_to_remove,
238 syncer::ModelTypeSet types_to_unapply) {
239 sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap
241 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
242 sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
245 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
246 sync_driver::BackendDataTypeConfigurer::DISABLED,
247 types_to_remove, &config_state_map);
248 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
249 sync_driver::BackendDataTypeConfigurer::UNREADY,
250 types_to_unapply, &config_state_map);
252 types_to_add.PutAll(syncer::ControlTypes());
253 backend_->ConfigureDataTypes(
254 syncer::CONFIGURE_REASON_RECONFIGURATION,
256 base::Bind(&SyncBackendHostTest::DownloadReady,
257 base::Unretained(this)),
258 base::Bind(&SyncBackendHostTest::OnDownloadRetry,
259 base::Unretained(this)));
260 base::RunLoop run_loop;
261 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
262 run_loop.QuitClosure(),
263 TestTimeouts::action_timeout());
267 void IssueRefreshRequest(syncer::ModelTypeSet types) {
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
270 content::NotificationService::current()->Notify(
271 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
272 content::Source<Profile>(profile_),
273 content::Details<syncer::ModelTypeSet>(&types));
277 void DownloadReady(syncer::ModelTypeSet succeeded_types,
278 syncer::ModelTypeSet failed_types) {
279 base::MessageLoop::current()->Quit();
282 void OnDownloadRetry() {
286 content::TestBrowserThreadBundle thread_bundle_;
287 StrictMock<MockSyncFrontend> mock_frontend_;
288 syncer::SyncCredentials credentials_;
289 TestingProfileManager profile_manager_;
290 TestingProfile* profile_;
291 scoped_ptr<sync_driver::SyncPrefs> sync_prefs_;
292 scoped_ptr<SyncBackendHost> backend_;
293 scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
294 FakeSyncManager* fake_manager_;
295 syncer::ModelTypeSet enabled_types_;
296 scoped_ptr<syncer::NetworkResources> network_resources_;
299 // Test basic initialization with no initial types (first time initialization).
300 // Only the nigori should be configured.
301 TEST_F(SyncBackendHostTest, InitShutdown) {
302 InitializeBackend(true);
303 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
304 syncer::ControlTypes()));
305 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
306 syncer::ControlTypes()));
307 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
308 syncer::ControlTypes()).Empty());
311 // Test first time sync scenario. All types should be properly configured.
312 TEST_F(SyncBackendHostTest, FirstTimeSync) {
313 InitializeBackend(true);
314 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
315 syncer::ControlTypes()));
316 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
317 syncer::ControlTypes()));
318 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
319 syncer::ControlTypes()).Empty());
321 ConfigureDataTypes(enabled_types_,
322 Difference(syncer::ModelTypeSet::All(),
324 syncer::ModelTypeSet());
325 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
326 Difference(enabled_types_, syncer::ControlTypes())));
327 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
328 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
329 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
330 enabled_types_).Empty());
333 // Test the restart after setting up sync scenario. No enabled types should be
334 // downloaded or cleaned.
335 TEST_F(SyncBackendHostTest, Restart) {
336 sync_prefs_->SetSyncSetupCompleted();
337 syncer::ModelTypeSet all_but_nigori = enabled_types_;
338 fake_manager_factory_->set_progress_marker_types(enabled_types_);
339 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
340 InitializeBackend(true);
341 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
342 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
343 enabled_types_).Empty());
344 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
345 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
346 enabled_types_).Empty());
348 ConfigureDataTypes(enabled_types_,
349 Difference(syncer::ModelTypeSet::All(),
351 syncer::ModelTypeSet());
352 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
353 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
354 enabled_types_).Empty());
355 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
356 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
357 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
358 enabled_types_).Empty());
361 // Test a sync restart scenario where some types had never finished configuring.
362 // The partial types should be purged, then reconfigured properly.
363 TEST_F(SyncBackendHostTest, PartialTypes) {
364 sync_prefs_->SetSyncSetupCompleted();
365 // Set sync manager behavior before passing it down. All types have progress
366 // markers, but nigori and bookmarks are missing initial sync ended.
367 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
368 syncer::ModelTypeSet full_types =
369 Difference(enabled_types_, partial_types);
370 fake_manager_factory_->set_progress_marker_types(enabled_types_);
371 fake_manager_factory_->set_initial_sync_ended_types(full_types);
373 // Bringing up the backend should purge all partial types, then proceed to
374 // download the Nigori.
375 InitializeBackend(true);
376 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
377 syncer::ModelTypeSet(syncer::NIGORI)));
378 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
379 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
380 Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
381 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
382 enabled_types_).Equals(
383 Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
385 // Now do the actual configuration, which should download and apply bookmarks.
386 ConfigureDataTypes(enabled_types_,
387 Difference(syncer::ModelTypeSet::All(),
389 syncer::ModelTypeSet());
390 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
391 enabled_types_).Empty());
392 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
394 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
395 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
396 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
397 enabled_types_).Empty());
400 // Test the behavior when we lose the sync db. Although we already have types
401 // enabled, we should re-download all of them because we lost their data.
402 TEST_F(SyncBackendHostTest, LostDB) {
403 sync_prefs_->SetSyncSetupCompleted();
404 // Initialization should fetch the Nigori node. Everything else should be
406 InitializeBackend(true);
407 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
408 syncer::ModelTypeSet(syncer::ControlTypes())));
409 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
410 syncer::ModelTypeSet(syncer::ControlTypes())));
411 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
412 enabled_types_).Equals(
413 Difference(enabled_types_, syncer::ControlTypes())));
415 // The database was empty, so any cleaning is entirely optional. We want to
416 // reset this value before running the next part of the test, though.
417 fake_manager_->GetAndResetCleanedTypes();
419 // The actual configuration should redownload and apply all the enabled types.
420 ConfigureDataTypes(enabled_types_,
421 Difference(syncer::ModelTypeSet::All(),
423 syncer::ModelTypeSet());
424 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
425 Difference(enabled_types_, syncer::ControlTypes())));
426 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
427 enabled_types_).Empty());
428 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
429 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
430 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
431 enabled_types_).Empty());
434 TEST_F(SyncBackendHostTest, DisableTypes) {
435 // Simulate first time sync.
436 InitializeBackend(true);
437 fake_manager_->GetAndResetCleanedTypes();
438 ConfigureDataTypes(enabled_types_,
439 Difference(syncer::ModelTypeSet::All(),
441 syncer::ModelTypeSet());
442 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
444 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
445 enabled_types_).Empty());
446 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
447 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
448 enabled_types_).Empty());
450 // Then disable two datatypes.
451 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
452 syncer::SEARCH_ENGINES);
453 syncer::ModelTypeSet old_types = enabled_types_;
454 enabled_types_.RemoveAll(disabled_types);
455 ConfigureDataTypes(enabled_types_,
456 Difference(syncer::ModelTypeSet::All(),
458 syncer::ModelTypeSet());
460 // Only those datatypes disabled should be cleaned. Nothing should be
462 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
463 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
464 old_types).Equals(disabled_types));
465 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
466 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
467 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
468 enabled_types_).Empty());
471 TEST_F(SyncBackendHostTest, AddTypes) {
472 // Simulate first time sync.
473 InitializeBackend(true);
474 fake_manager_->GetAndResetCleanedTypes();
475 ConfigureDataTypes(enabled_types_,
476 Difference(syncer::ModelTypeSet::All(),
478 syncer::ModelTypeSet());
479 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
481 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
482 enabled_types_).Empty());
483 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
484 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
485 enabled_types_).Empty());
487 // Then add two datatypes.
488 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
490 enabled_types_.PutAll(new_types);
491 ConfigureDataTypes(enabled_types_,
492 Difference(syncer::ModelTypeSet::All(),
494 syncer::ModelTypeSet());
496 // Only those datatypes added should be downloaded (plus nigori). Nothing
497 // should be cleaned aside from the disabled types.
498 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
499 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
500 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
501 enabled_types_).Empty());
502 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
503 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
504 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
505 enabled_types_).Empty());
508 // And and disable in the same configuration.
509 TEST_F(SyncBackendHostTest, AddDisableTypes) {
510 // Simulate first time sync.
511 InitializeBackend(true);
512 fake_manager_->GetAndResetCleanedTypes();
513 ConfigureDataTypes(enabled_types_,
514 Difference(syncer::ModelTypeSet::All(),
516 syncer::ModelTypeSet());
517 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
519 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
520 enabled_types_).Empty());
521 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
522 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
523 enabled_types_).Empty());
525 // Then add two datatypes.
526 syncer::ModelTypeSet old_types = enabled_types_;
527 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
528 syncer::SEARCH_ENGINES);
529 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
531 enabled_types_.PutAll(new_types);
532 enabled_types_.RemoveAll(disabled_types);
533 ConfigureDataTypes(enabled_types_,
534 Difference(syncer::ModelTypeSet::All(),
536 syncer::ModelTypeSet());
538 // Only those datatypes added should be downloaded (plus nigori). Nothing
539 // should be cleaned aside from the disabled types.
540 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
541 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
542 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
543 old_types).Equals(disabled_types));
544 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
545 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
546 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
547 old_types).Equals(disabled_types));
550 // Test restarting the browser to newly supported datatypes. The new datatypes
551 // should be downloaded on the configuration after backend initialization.
552 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
553 sync_prefs_->SetSyncSetupCompleted();
554 // Set sync manager behavior before passing it down. All types have progress
555 // markers and initial sync ended except the new types.
556 syncer::ModelTypeSet old_types = enabled_types_;
557 fake_manager_factory_->set_progress_marker_types(old_types);
558 fake_manager_factory_->set_initial_sync_ended_types(old_types);
559 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
560 syncer::EXTENSION_SETTINGS);
561 enabled_types_.PutAll(new_types);
564 InitializeBackend(true);
565 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
566 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
568 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
569 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
570 enabled_types_).Equals(new_types));
572 // Downloads and applies the new types.
573 ConfigureDataTypes(enabled_types_,
574 Difference(syncer::ModelTypeSet::All(),
576 syncer::ModelTypeSet());
577 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
578 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
579 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
580 enabled_types_).Empty());
581 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
582 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
583 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
584 enabled_types_).Empty());
587 // Test the newly supported types scenario, but with the presence of partial
588 // types as well. Both partial and newly supported types should be downloaded
589 // the configuration.
590 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
591 sync_prefs_->SetSyncSetupCompleted();
592 // Set sync manager behavior before passing it down. All types have progress
593 // markers and initial sync ended except the new types.
594 syncer::ModelTypeSet old_types = enabled_types_;
595 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
596 syncer::ModelTypeSet full_types =
597 Difference(enabled_types_, partial_types);
598 fake_manager_factory_->set_progress_marker_types(old_types);
599 fake_manager_factory_->set_initial_sync_ended_types(full_types);
600 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
601 syncer::EXTENSION_SETTINGS);
602 enabled_types_.PutAll(new_types);
604 // Purge the partial types. The nigori will be among the purged types, but
605 // the syncer will re-download it by the time the initialization is complete.
606 InitializeBackend(true);
607 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
608 syncer::ModelTypeSet(syncer::NIGORI)));
609 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
610 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
611 syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
612 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
613 enabled_types_).Equals(Union(new_types, Difference(
614 partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
616 // Downloads and applies the new types and partial types (which includes
618 ConfigureDataTypes(enabled_types_,
619 Difference(syncer::ModelTypeSet::All(),
621 syncer::ModelTypeSet());
622 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
623 Union(new_types, partial_types)));
624 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
625 enabled_types_).Empty());
626 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
627 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
628 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
629 enabled_types_).Empty());
632 // Verify that downloading control types only downloads those types that do
633 // not have initial sync ended set.
634 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
635 sync_prefs_->SetSyncSetupCompleted();
636 // Set sync manager behavior before passing it down. Experiments and device
637 // info are new types without progress markers or initial sync ended, while
638 // all other types have been fully downloaded and applied.
639 syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::NIGORI);
640 syncer::ModelTypeSet old_types =
641 Difference(enabled_types_, new_types);
642 fake_manager_factory_->set_progress_marker_types(old_types);
643 fake_manager_factory_->set_initial_sync_ended_types(old_types);
645 // Bringing up the backend should download the new types without downloading
647 InitializeBackend(true);
648 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
649 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
650 Difference(syncer::ModelTypeSet::All(),
652 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
653 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
654 enabled_types_).Empty());
657 // Fail to download control types. It's believed that there is a server bug
658 // which can allow this to happen (crbug.com/164288). The sync backend host
659 // should detect this condition and fail to initialize the backend.
661 // The failure is "silent" in the sense that the GetUpdates request appears to
662 // be successful, but it returned no results. This means that the usual
663 // download retry logic will not be invoked.
664 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
665 fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
666 InitializeBackend(false);
669 // Test that local refresh requests are delivered to sync.
670 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
671 InitializeBackend(true);
673 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
674 IssueRefreshRequest(set1);
675 fake_manager_->WaitForSyncThread();
676 EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
678 syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
679 IssueRefreshRequest(set2);
680 fake_manager_->WaitForSyncThread();
681 EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
684 // Test that local invalidations issued before sync is initialized are ignored.
685 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
686 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
687 IssueRefreshRequest(set1);
689 InitializeBackend(true);
691 fake_manager_->WaitForSyncThread();
692 EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
695 // Test that local invalidations issued while sync is shutting down are ignored.
696 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
697 InitializeBackend(true);
699 backend_->StopSyncingForShutdown();
701 syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
702 IssueRefreshRequest(types);
703 fake_manager_->WaitForSyncThread();
704 EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
706 backend_->Shutdown(syncer::STOP_SYNC);
710 // Test that configuration on signin sends the proper GU source.
711 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
712 InitializeBackend(true);
713 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
714 fake_manager_->GetAndResetConfigureReason());
717 // Test that configuration on restart sends the proper GU source.
718 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
719 sync_prefs_->SetSyncSetupCompleted();
720 fake_manager_factory_->set_progress_marker_types(enabled_types_);
721 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
722 InitializeBackend(true);
723 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
724 fake_manager_->GetAndResetConfigureReason());
727 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
728 // setup hasn't been completed. This test ensures that cleanup happens.
729 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) {
730 const char* nonsense = "slon";
731 base::FilePath temp_directory =
732 profile_->GetPath().Append(base::FilePath(kTestSyncDir));
733 base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3");
734 ASSERT_TRUE(base::CreateDirectory(temp_directory));
735 ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense)));
737 InitializeBackend(true);
739 EXPECT_FALSE(base::PathExists(sync_file));
742 // If bookmarks encounter an error that results in disabling without purging
743 // (such as when the type is unready), and then is explicitly disabled, the
744 // SyncBackendHost needs to tell the manager to purge the type, even though
745 // it's already disabled (crbug.com/386778).
746 TEST_F(SyncBackendHostTest, DisableThenPurgeType) {
747 syncer::ModelTypeSet error_types(syncer::BOOKMARKS);
749 InitializeBackend(true);
751 // First enable the types.
752 ConfigureDataTypes(enabled_types_,
753 Difference(syncer::ModelTypeSet::All(),
755 syncer::ModelTypeSet());
757 // Then mark the error types as unready (disables without purging).
758 ConfigureDataTypes(enabled_types_,
759 Difference(syncer::ModelTypeSet::All(),
762 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
763 error_types).Empty());
765 // Lastly explicitly disable the error types, which should result in a purge.
766 enabled_types_.RemoveAll(error_types);
767 ConfigureDataTypes(enabled_types_,
768 Difference(syncer::ModelTypeSet::All(),
770 syncer::ModelTypeSet());
771 EXPECT_FALSE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
772 error_types).Empty());
777 } // namespace browser_sync