1 // Copyright (c) 2012 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.h"
9 #include "base/location.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/test/test_timeouts.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/invalidation/invalidator_storage.h"
16 #include "chrome/browser/prefs/pref_service_syncable.h"
17 #include "chrome/browser/sync/glue/device_info.h"
18 #include "chrome/browser/sync/glue/synced_device_tracker.h"
19 #include "chrome/browser/sync/sync_prefs.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "components/user_prefs/pref_registry_syncable.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "content/public/test/test_utils.h"
25 #include "google/cacheinvalidation/include/types.h"
26 #include "net/url_request/test_url_fetcher_factory.h"
27 #include "sync/internal_api/public/base/model_type.h"
28 #include "sync/internal_api/public/engine/model_safe_worker.h"
29 #include "sync/internal_api/public/sync_manager_factory.h"
30 #include "sync/internal_api/public/test/fake_sync_manager.h"
31 #include "sync/internal_api/public/util/experiments.h"
32 #include "sync/notifier/invalidator_state.h"
33 #include "sync/protocol/encryption.pb.h"
34 #include "sync/protocol/sync_protocol_error.h"
35 #include "sync/util/test_unrecoverable_error_handler.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
40 using content::BrowserThread;
41 using syncer::FakeSyncManager;
42 using syncer::SyncManager;
43 using ::testing::InvokeWithoutArgs;
44 using ::testing::StrictMock;
47 namespace browser_sync {
51 ACTION_P(Signal, event) {
55 void QuitMessageLoop() {
56 base::MessageLoop::current()->Quit();
59 class MockSyncFrontend : public SyncFrontend {
61 virtual ~MockSyncFrontend() {}
63 MOCK_METHOD1(OnInvalidatorStateChange,
64 void(syncer::InvalidatorState));
65 MOCK_METHOD1(OnIncomingInvalidation,
66 void(const syncer::ObjectIdInvalidationMap&));
69 void(const syncer::WeakHandle<syncer::JsBackend>&,
70 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&,
72 MOCK_METHOD0(OnSyncCycleCompleted, void());
73 MOCK_METHOD1(OnConnectionStatusChange,
74 void(syncer::ConnectionStatus status));
75 MOCK_METHOD0(OnStopSyncingPermanently, void());
76 MOCK_METHOD0(OnClearServerDataSucceeded, void());
77 MOCK_METHOD0(OnClearServerDataFailed, void());
78 MOCK_METHOD2(OnPassphraseRequired,
79 void(syncer::PassphraseRequiredReason,
80 const sync_pb::EncryptedData&));
81 MOCK_METHOD0(OnPassphraseAccepted, void());
82 MOCK_METHOD2(OnEncryptedTypesChanged,
83 void(syncer::ModelTypeSet, bool));
84 MOCK_METHOD0(OnEncryptionComplete, void());
85 MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet));
86 MOCK_METHOD1(OnExperimentsChanged,
87 void(const syncer::Experiments&));
88 MOCK_METHOD1(OnActionableError,
89 void(const syncer::SyncProtocolError& sync_error));
90 MOCK_METHOD0(OnSyncConfigureRetry, void());
93 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
95 explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager)
96 : fake_manager_(fake_manager) {
97 *fake_manager_ = NULL;
99 virtual ~FakeSyncManagerFactory() {}
101 // SyncManagerFactory implementation. Called on the sync thread.
102 virtual scoped_ptr<SyncManager> CreateSyncManager(
103 std::string name) OVERRIDE {
104 *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_,
105 progress_marker_types_,
106 configure_fail_types_);
107 return scoped_ptr<SyncManager>(*fake_manager_);
110 void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
111 initial_sync_ended_types_ = types;
114 void set_progress_marker_types(syncer::ModelTypeSet types) {
115 progress_marker_types_ = types;
118 void set_configure_fail_types(syncer::ModelTypeSet types) {
119 configure_fail_types_ = types;
123 syncer::ModelTypeSet initial_sync_ended_types_;
124 syncer::ModelTypeSet progress_marker_types_;
125 syncer::ModelTypeSet configure_fail_types_;
126 FakeSyncManager** fake_manager_;
129 class SyncBackendHostTest : public testing::Test {
131 SyncBackendHostTest()
132 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
133 fake_manager_(NULL) {}
135 virtual ~SyncBackendHostTest() {}
137 virtual void SetUp() OVERRIDE {
138 profile_.reset(new TestingProfile());
139 sync_prefs_.reset(new SyncPrefs(profile_->GetPrefs()));
140 backend_.reset(new SyncBackendHost(
141 profile_->GetDebugName(),
143 sync_prefs_->AsWeakPtr()));
144 credentials_.email = "user@example.com";
145 credentials_.sync_token = "sync_token";
147 fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
149 // These types are always implicitly enabled.
150 enabled_types_.PutAll(syncer::ControlTypes());
152 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
153 // Registrar removing them if it can't find their model workers.
154 enabled_types_.Put(syncer::BOOKMARKS);
155 enabled_types_.Put(syncer::NIGORI);
156 enabled_types_.Put(syncer::DEVICE_INFO);
157 enabled_types_.Put(syncer::PREFERENCES);
158 enabled_types_.Put(syncer::SESSIONS);
159 enabled_types_.Put(syncer::SEARCH_ENGINES);
160 enabled_types_.Put(syncer::AUTOFILL);
161 enabled_types_.Put(syncer::EXPERIMENTS);
164 virtual void TearDown() OVERRIDE {
166 backend_->StopSyncingForShutdown();
167 backend_->Shutdown(SyncBackendHost::STOP);
172 // Pump messages posted by the sync thread (which may end up
173 // posting on the IO thread).
174 base::RunLoop().RunUntilIdle();
175 content::RunAllPendingInMessageLoop(BrowserThread::IO);
176 // Pump any messages posted by the IO thread.
177 base::RunLoop().RunUntilIdle();
180 // Synchronously initializes the backend.
181 void InitializeBackend(bool expect_success) {
182 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, expect_success)).
183 WillOnce(InvokeWithoutArgs(QuitMessageLoop));
184 backend_->Initialize(
186 scoped_ptr<base::Thread>(),
187 syncer::WeakHandle<syncer::JsEventHandler>(),
191 fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
192 scoped_ptr<syncer::UnrecoverableErrorHandler>(
193 new syncer::TestUnrecoverableErrorHandler).Pass(),
195 base::RunLoop run_loop;
196 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
197 run_loop.QuitClosure(),
198 TestTimeouts::action_timeout());
200 // |fake_manager_factory_|'s fake_manager() is set on the sync
201 // thread, but we can rely on the message loop barriers to
202 // guarantee that we see the updated value.
203 DCHECK(fake_manager_);
206 // Synchronously configures the backend's datatypes.
207 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add,
208 syncer::ModelTypeSet types_to_remove) {
209 BackendDataTypeConfigurer::DataTypeConfigStateMap config_state_map;
210 BackendDataTypeConfigurer::SetDataTypesState(
211 BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
214 BackendDataTypeConfigurer::SetDataTypesState(
215 BackendDataTypeConfigurer::DISABLED,
216 types_to_remove, &config_state_map);
218 types_to_add.PutAll(syncer::ControlTypes());
219 backend_->ConfigureDataTypes(
220 syncer::CONFIGURE_REASON_RECONFIGURATION,
222 base::Bind(&SyncBackendHostTest::DownloadReady,
223 base::Unretained(this)),
224 base::Bind(&SyncBackendHostTest::OnDownloadRetry,
225 base::Unretained(this)));
226 base::RunLoop run_loop;
227 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
228 run_loop.QuitClosure(),
229 TestTimeouts::action_timeout());
233 void IssueRefreshRequest(syncer::ModelTypeSet types) {
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
236 content::NotificationService::current()->Notify(
237 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
238 content::Source<Profile>(profile_.get()),
239 content::Details<syncer::ModelTypeSet>(&types));
243 void DownloadReady(syncer::ModelTypeSet succeeded_types,
244 syncer::ModelTypeSet failed_types) {
245 base::MessageLoop::current()->Quit();
248 void OnDownloadRetry() {
252 content::TestBrowserThreadBundle thread_bundle_;
253 StrictMock<MockSyncFrontend> mock_frontend_;
254 syncer::SyncCredentials credentials_;
255 scoped_ptr<TestingProfile> profile_;
256 scoped_ptr<SyncPrefs> sync_prefs_;
257 scoped_ptr<SyncBackendHost> backend_;
258 scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
259 FakeSyncManager* fake_manager_;
260 syncer::ModelTypeSet enabled_types_;
263 // Test basic initialization with no initial types (first time initialization).
264 // Only the nigori should be configured.
265 TEST_F(SyncBackendHostTest, InitShutdown) {
266 InitializeBackend(true);
267 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
268 syncer::ControlTypes()));
269 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
270 syncer::ControlTypes()));
271 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
272 syncer::ControlTypes()).Empty());
275 // Test first time sync scenario. All types should be properly configured.
276 TEST_F(SyncBackendHostTest, FirstTimeSync) {
277 InitializeBackend(true);
278 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
279 syncer::ControlTypes()));
280 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
281 syncer::ControlTypes()));
282 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
283 syncer::ControlTypes()).Empty());
285 ConfigureDataTypes(enabled_types_,
286 Difference(syncer::ModelTypeSet::All(),
288 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
289 Difference(enabled_types_, syncer::ControlTypes())));
290 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
291 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
292 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
293 enabled_types_).Empty());
296 // Test the restart after setting up sync scenario. No enabled types should be
297 // downloaded or cleaned.
298 TEST_F(SyncBackendHostTest, Restart) {
299 sync_prefs_->SetSyncSetupCompleted();
300 syncer::ModelTypeSet all_but_nigori = enabled_types_;
301 fake_manager_factory_->set_progress_marker_types(enabled_types_);
302 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
303 InitializeBackend(true);
304 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
305 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
306 enabled_types_).Empty());
307 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
308 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
309 enabled_types_).Empty());
311 ConfigureDataTypes(enabled_types_,
312 Difference(syncer::ModelTypeSet::All(),
314 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
315 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
316 enabled_types_).Empty());
317 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
318 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
319 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
320 enabled_types_).Empty());
323 // Test a sync restart scenario where some types had never finished configuring.
324 // The partial types should be purged, then reconfigured properly.
325 TEST_F(SyncBackendHostTest, PartialTypes) {
326 sync_prefs_->SetSyncSetupCompleted();
327 // Set sync manager behavior before passing it down. All types have progress
328 // markers, but nigori and bookmarks are missing initial sync ended.
329 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
330 syncer::ModelTypeSet full_types =
331 Difference(enabled_types_, partial_types);
332 fake_manager_factory_->set_progress_marker_types(enabled_types_);
333 fake_manager_factory_->set_initial_sync_ended_types(full_types);
335 // Bringing up the backend should purge all partial types, then proceed to
336 // download the Nigori.
337 InitializeBackend(true);
338 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
339 syncer::ModelTypeSet(syncer::NIGORI)));
340 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
341 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
342 Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
343 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
344 enabled_types_).Equals(
345 Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
347 // Now do the actual configuration, which should download and apply bookmarks.
348 ConfigureDataTypes(enabled_types_,
349 Difference(syncer::ModelTypeSet::All(),
351 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
352 enabled_types_).Empty());
353 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
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 the behavior when we lose the sync db. Although we already have types
362 // enabled, we should re-download all of them because we lost their data.
363 TEST_F(SyncBackendHostTest, LostDB) {
364 sync_prefs_->SetSyncSetupCompleted();
365 // Initialization should fetch the Nigori node. Everything else should be
367 InitializeBackend(true);
368 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
369 syncer::ModelTypeSet(syncer::ControlTypes())));
370 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
371 syncer::ModelTypeSet(syncer::ControlTypes())));
372 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
373 enabled_types_).Equals(
374 Difference(enabled_types_, syncer::ControlTypes())));
376 // The database was empty, so any cleaning is entirely optional. We want to
377 // reset this value before running the next part of the test, though.
378 fake_manager_->GetAndResetCleanedTypes();
380 // The actual configuration should redownload and apply all the enabled types.
381 ConfigureDataTypes(enabled_types_,
382 Difference(syncer::ModelTypeSet::All(),
384 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
385 Difference(enabled_types_, syncer::ControlTypes())));
386 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
387 enabled_types_).Empty());
388 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
389 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
390 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
391 enabled_types_).Empty());
394 TEST_F(SyncBackendHostTest, DisableTypes) {
395 // Simulate first time sync.
396 InitializeBackend(true);
397 fake_manager_->GetAndResetCleanedTypes();
398 ConfigureDataTypes(enabled_types_,
399 Difference(syncer::ModelTypeSet::All(),
401 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
403 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
404 enabled_types_).Empty());
405 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
406 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
407 enabled_types_).Empty());
409 // Then disable two datatypes.
410 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
411 syncer::SEARCH_ENGINES);
412 syncer::ModelTypeSet old_types = enabled_types_;
413 enabled_types_.RemoveAll(disabled_types);
414 ConfigureDataTypes(enabled_types_,
415 Difference(syncer::ModelTypeSet::All(),
418 // Only those datatypes disabled should be cleaned. Nothing should be
420 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
421 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
422 old_types).Equals(disabled_types));
423 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
424 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
425 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
426 enabled_types_).Empty());
429 TEST_F(SyncBackendHostTest, AddTypes) {
430 // Simulate first time sync.
431 InitializeBackend(true);
432 fake_manager_->GetAndResetCleanedTypes();
433 ConfigureDataTypes(enabled_types_,
434 Difference(syncer::ModelTypeSet::All(),
436 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
438 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
439 enabled_types_).Empty());
440 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
441 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
442 enabled_types_).Empty());
444 // Then add two datatypes.
445 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
447 enabled_types_.PutAll(new_types);
448 ConfigureDataTypes(enabled_types_,
449 Difference(syncer::ModelTypeSet::All(),
452 // Only those datatypes added should be downloaded (plus nigori). Nothing
453 // should be cleaned aside from the disabled types.
454 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
455 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
456 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
457 enabled_types_).Empty());
458 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
459 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
460 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
461 enabled_types_).Empty());
464 // And and disable in the same configuration.
465 TEST_F(SyncBackendHostTest, AddDisableTypes) {
466 // Simulate first time sync.
467 InitializeBackend(true);
468 fake_manager_->GetAndResetCleanedTypes();
469 ConfigureDataTypes(enabled_types_,
470 Difference(syncer::ModelTypeSet::All(),
472 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
474 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
475 enabled_types_).Empty());
476 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
477 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
478 enabled_types_).Empty());
480 // Then add two datatypes.
481 syncer::ModelTypeSet old_types = enabled_types_;
482 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
483 syncer::SEARCH_ENGINES);
484 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
486 enabled_types_.PutAll(new_types);
487 enabled_types_.RemoveAll(disabled_types);
488 ConfigureDataTypes(enabled_types_,
489 Difference(syncer::ModelTypeSet::All(),
492 // Only those datatypes added should be downloaded (plus nigori). Nothing
493 // should be cleaned aside from the disabled types.
494 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
495 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
496 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
497 old_types).Equals(disabled_types));
498 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
499 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
500 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
501 old_types).Equals(disabled_types));
504 // Test restarting the browser to newly supported datatypes. The new datatypes
505 // should be downloaded on the configuration after backend initialization.
506 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
507 sync_prefs_->SetSyncSetupCompleted();
508 // Set sync manager behavior before passing it down. All types have progress
509 // markers and initial sync ended except the new types.
510 syncer::ModelTypeSet old_types = enabled_types_;
511 fake_manager_factory_->set_progress_marker_types(old_types);
512 fake_manager_factory_->set_initial_sync_ended_types(old_types);
513 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
514 syncer::EXTENSION_SETTINGS);
515 enabled_types_.PutAll(new_types);
518 InitializeBackend(true);
519 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
520 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
522 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
523 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
524 enabled_types_).Equals(new_types));
526 // Downloads and applies the new types.
527 ConfigureDataTypes(enabled_types_,
528 Difference(syncer::ModelTypeSet::All(),
530 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
531 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
532 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
533 enabled_types_).Empty());
534 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
535 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
536 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
537 enabled_types_).Empty());
540 // Test the newly supported types scenario, but with the presence of partial
541 // types as well. Both partial and newly supported types should be downloaded
542 // the configuration.
543 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
544 sync_prefs_->SetSyncSetupCompleted();
545 // Set sync manager behavior before passing it down. All types have progress
546 // markers and initial sync ended except the new types.
547 syncer::ModelTypeSet old_types = enabled_types_;
548 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
549 syncer::ModelTypeSet full_types =
550 Difference(enabled_types_, partial_types);
551 fake_manager_factory_->set_progress_marker_types(old_types);
552 fake_manager_factory_->set_initial_sync_ended_types(full_types);
553 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
554 syncer::EXTENSION_SETTINGS);
555 enabled_types_.PutAll(new_types);
557 // Purge the partial types. The nigori will be among the purged types, but
558 // the syncer will re-download it by the time the initialization is complete.
559 InitializeBackend(true);
560 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
561 syncer::ModelTypeSet(syncer::NIGORI)));
562 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
563 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
564 syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
565 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
566 enabled_types_).Equals(Union(new_types, Difference(
567 partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
569 // Downloads and applies the new types and partial types (which includes
571 ConfigureDataTypes(enabled_types_,
572 Difference(syncer::ModelTypeSet::All(),
574 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
575 Union(new_types, partial_types)));
576 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
577 enabled_types_).Empty());
578 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
579 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
580 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
581 enabled_types_).Empty());
584 // Ensure the device info tracker is initialized properly on startup.
585 TEST_F(SyncBackendHostTest, InitializeDeviceInfo) {
586 ASSERT_EQ(NULL, backend_->GetSyncedDeviceTracker());
588 InitializeBackend(true);
589 const SyncedDeviceTracker* device_tracker =
590 backend_->GetSyncedDeviceTracker();
591 ASSERT_TRUE(device_tracker->ReadLocalDeviceInfo());
594 // Verify that downloading control types only downloads those types that do
595 // not have initial sync ended set.
596 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
597 sync_prefs_->SetSyncSetupCompleted();
598 // Set sync manager behavior before passing it down. Experiments and device
599 // info are new types without progress markers or initial sync ended, while
600 // all other types have been fully downloaded and applied.
601 syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::DEVICE_INFO);
602 syncer::ModelTypeSet old_types =
603 Difference(enabled_types_, new_types);
604 fake_manager_factory_->set_progress_marker_types(old_types);
605 fake_manager_factory_->set_initial_sync_ended_types(old_types);
607 // Bringing up the backend should download the new types without downloading
609 InitializeBackend(true);
610 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
611 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
612 Difference(syncer::ModelTypeSet::All(),
614 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
615 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
616 enabled_types_).Empty());
619 // Fail to download control types. It's believed that there is a server bug
620 // which can allow this to happen (crbug.com/164288). The sync backend host
621 // should detect this condition and fail to initialize the backend.
623 // The failure is "silent" in the sense that the GetUpdates request appears to
624 // be successful, but it returned no results. This means that the usual
625 // download retry logic will not be invoked.
626 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
627 fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
628 InitializeBackend(false);
631 // Test that local refresh requests are delivered to sync.
632 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
633 InitializeBackend(true);
635 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
636 IssueRefreshRequest(set1);
637 fake_manager_->WaitForSyncThread();
638 EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
640 syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
641 IssueRefreshRequest(set2);
642 fake_manager_->WaitForSyncThread();
643 EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
646 // Test that local invalidations issued before sync is initialized are ignored.
647 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
648 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
649 IssueRefreshRequest(set1);
651 InitializeBackend(true);
653 fake_manager_->WaitForSyncThread();
654 EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
657 // Test that local invalidations issued while sync is shutting down are ignored.
658 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
659 InitializeBackend(true);
661 backend_->StopSyncingForShutdown();
663 syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
664 IssueRefreshRequest(types);
665 fake_manager_->WaitForSyncThread();
666 EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
668 backend_->Shutdown(SyncBackendHost::STOP);
672 // Test that configuration on signin sends the proper GU source.
673 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
674 InitializeBackend(true);
675 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
676 fake_manager_->GetAndResetConfigureReason());
679 // Test that configuration on restart sends the proper GU source.
680 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
681 sync_prefs_->SetSyncSetupCompleted();
682 fake_manager_factory_->set_progress_marker_types(enabled_types_);
683 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
684 InitializeBackend(true);
685 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
686 fake_manager_->GetAndResetConfigureReason());
691 } // namespace browser_sync