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/invalidator_storage.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/browser/sync/sync_prefs.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "components/sync_driver/sync_frontend.h"
23 #include "components/user_prefs/pref_registry_syncable.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "content/public/test/test_utils.h"
27 #include "google/cacheinvalidation/include/types.h"
28 #include "net/url_request/test_url_fetcher_factory.h"
29 #include "sync/internal_api/public/base/model_type.h"
30 #include "sync/internal_api/public/engine/model_safe_worker.h"
31 #include "sync/internal_api/public/http_bridge_network_resources.h"
32 #include "sync/internal_api/public/network_resources.h"
33 #include "sync/internal_api/public/sync_manager_factory.h"
34 #include "sync/internal_api/public/test/fake_sync_manager.h"
35 #include "sync/internal_api/public/util/experiments.h"
36 #include "sync/notifier/invalidator_state.h"
37 #include "sync/protocol/encryption.pb.h"
38 #include "sync/protocol/sync_protocol_error.h"
39 #include "sync/util/test_unrecoverable_error_handler.h"
40 #include "testing/gmock/include/gmock/gmock.h"
41 #include "testing/gtest/include/gtest/gtest.h"
44 using content::BrowserThread;
45 using syncer::FakeSyncManager;
46 using syncer::SyncManager;
47 using ::testing::InvokeWithoutArgs;
48 using ::testing::StrictMock;
51 namespace browser_sync {
55 ACTION_P(Signal, event) {
59 void QuitMessageLoop() {
60 base::MessageLoop::current()->Quit();
63 class MockSyncFrontend : public SyncFrontend {
65 virtual ~MockSyncFrontend() {}
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(OnClearServerDataSucceeded, void());
76 MOCK_METHOD0(OnClearServerDataFailed, void());
77 MOCK_METHOD2(OnPassphraseRequired,
78 void(syncer::PassphraseRequiredReason,
79 const sync_pb::EncryptedData&));
80 MOCK_METHOD0(OnPassphraseAccepted, void());
81 MOCK_METHOD2(OnEncryptedTypesChanged,
82 void(syncer::ModelTypeSet, bool));
83 MOCK_METHOD0(OnEncryptionComplete, void());
84 MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet));
85 MOCK_METHOD1(OnExperimentsChanged,
86 void(const syncer::Experiments&));
87 MOCK_METHOD1(OnActionableError,
88 void(const syncer::SyncProtocolError& sync_error));
89 MOCK_METHOD0(OnSyncConfigureRetry, void());
92 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
94 explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager)
95 : fake_manager_(fake_manager) {
96 *fake_manager_ = NULL;
98 virtual ~FakeSyncManagerFactory() {}
100 // SyncManagerFactory implementation. Called on the sync thread.
101 virtual scoped_ptr<SyncManager> CreateSyncManager(
102 std::string name) OVERRIDE {
103 *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_,
104 progress_marker_types_,
105 configure_fail_types_);
106 return scoped_ptr<SyncManager>(*fake_manager_);
109 void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
110 initial_sync_ended_types_ = types;
113 void set_progress_marker_types(syncer::ModelTypeSet types) {
114 progress_marker_types_ = types;
117 void set_configure_fail_types(syncer::ModelTypeSet types) {
118 configure_fail_types_ = types;
122 syncer::ModelTypeSet initial_sync_ended_types_;
123 syncer::ModelTypeSet progress_marker_types_;
124 syncer::ModelTypeSet configure_fail_types_;
125 FakeSyncManager** fake_manager_;
128 class SyncBackendHostTest : public testing::Test {
130 SyncBackendHostTest()
131 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
132 fake_manager_(NULL) {}
134 virtual ~SyncBackendHostTest() {}
136 virtual void SetUp() OVERRIDE {
137 profile_.reset(new TestingProfile());
138 sync_prefs_.reset(new SyncPrefs(profile_->GetPrefs()));
139 backend_.reset(new SyncBackendHostImpl(
140 profile_->GetDebugName(),
142 sync_prefs_->AsWeakPtr()));
143 credentials_.email = "user@example.com";
144 credentials_.sync_token = "sync_token";
146 fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
148 // These types are always implicitly enabled.
149 enabled_types_.PutAll(syncer::ControlTypes());
151 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
152 // Registrar removing them if it can't find their model workers.
153 enabled_types_.Put(syncer::BOOKMARKS);
154 enabled_types_.Put(syncer::NIGORI);
155 enabled_types_.Put(syncer::DEVICE_INFO);
156 enabled_types_.Put(syncer::PREFERENCES);
157 enabled_types_.Put(syncer::SESSIONS);
158 enabled_types_.Put(syncer::SEARCH_ENGINES);
159 enabled_types_.Put(syncer::AUTOFILL);
160 enabled_types_.Put(syncer::EXPERIMENTS);
162 network_resources_.reset(new syncer::HttpBridgeNetworkResources());
165 virtual void TearDown() OVERRIDE {
167 backend_->StopSyncingForShutdown();
168 backend_->Shutdown(SyncBackendHost::STOP);
173 // Pump messages posted by the sync thread (which may end up
174 // posting on the IO thread).
175 base::RunLoop().RunUntilIdle();
176 content::RunAllPendingInMessageLoop(BrowserThread::IO);
177 // Pump any messages posted by the IO thread.
178 base::RunLoop().RunUntilIdle();
181 // Synchronously initializes the backend.
182 void InitializeBackend(bool expect_success) {
183 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, expect_success)).
184 WillOnce(InvokeWithoutArgs(QuitMessageLoop));
185 backend_->Initialize(
187 scoped_ptr<base::Thread>(),
188 syncer::WeakHandle<syncer::JsEventHandler>(),
192 fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
193 scoped_ptr<syncer::UnrecoverableErrorHandler>(
194 new syncer::TestUnrecoverableErrorHandler).Pass(),
196 network_resources_.get());
197 base::RunLoop run_loop;
198 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
199 run_loop.QuitClosure(),
200 TestTimeouts::action_timeout());
202 // |fake_manager_factory_|'s fake_manager() is set on the sync
203 // thread, but we can rely on the message loop barriers to
204 // guarantee that we see the updated value.
205 DCHECK(fake_manager_);
208 // Synchronously configures the backend's datatypes.
209 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add,
210 syncer::ModelTypeSet types_to_remove) {
211 BackendDataTypeConfigurer::DataTypeConfigStateMap config_state_map;
212 BackendDataTypeConfigurer::SetDataTypesState(
213 BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
216 BackendDataTypeConfigurer::SetDataTypesState(
217 BackendDataTypeConfigurer::DISABLED,
218 types_to_remove, &config_state_map);
220 types_to_add.PutAll(syncer::ControlTypes());
221 backend_->ConfigureDataTypes(
222 syncer::CONFIGURE_REASON_RECONFIGURATION,
224 base::Bind(&SyncBackendHostTest::DownloadReady,
225 base::Unretained(this)),
226 base::Bind(&SyncBackendHostTest::OnDownloadRetry,
227 base::Unretained(this)));
228 base::RunLoop run_loop;
229 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
230 run_loop.QuitClosure(),
231 TestTimeouts::action_timeout());
235 void IssueRefreshRequest(syncer::ModelTypeSet types) {
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238 content::NotificationService::current()->Notify(
239 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
240 content::Source<Profile>(profile_.get()),
241 content::Details<syncer::ModelTypeSet>(&types));
245 void DownloadReady(syncer::ModelTypeSet succeeded_types,
246 syncer::ModelTypeSet failed_types) {
247 base::MessageLoop::current()->Quit();
250 void OnDownloadRetry() {
254 content::TestBrowserThreadBundle thread_bundle_;
255 StrictMock<MockSyncFrontend> mock_frontend_;
256 syncer::SyncCredentials credentials_;
257 scoped_ptr<TestingProfile> profile_;
258 scoped_ptr<SyncPrefs> sync_prefs_;
259 scoped_ptr<SyncBackendHost> backend_;
260 scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
261 FakeSyncManager* fake_manager_;
262 syncer::ModelTypeSet enabled_types_;
263 scoped_ptr<syncer::NetworkResources> network_resources_;
266 // Test basic initialization with no initial types (first time initialization).
267 // Only the nigori should be configured.
268 TEST_F(SyncBackendHostTest, InitShutdown) {
269 InitializeBackend(true);
270 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
271 syncer::ControlTypes()));
272 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
273 syncer::ControlTypes()));
274 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
275 syncer::ControlTypes()).Empty());
278 // Test first time sync scenario. All types should be properly configured.
279 TEST_F(SyncBackendHostTest, FirstTimeSync) {
280 InitializeBackend(true);
281 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
282 syncer::ControlTypes()));
283 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
284 syncer::ControlTypes()));
285 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
286 syncer::ControlTypes()).Empty());
288 ConfigureDataTypes(enabled_types_,
289 Difference(syncer::ModelTypeSet::All(),
291 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
292 Difference(enabled_types_, syncer::ControlTypes())));
293 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
294 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
295 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
296 enabled_types_).Empty());
299 // Test the restart after setting up sync scenario. No enabled types should be
300 // downloaded or cleaned.
301 TEST_F(SyncBackendHostTest, Restart) {
302 sync_prefs_->SetSyncSetupCompleted();
303 syncer::ModelTypeSet all_but_nigori = enabled_types_;
304 fake_manager_factory_->set_progress_marker_types(enabled_types_);
305 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
306 InitializeBackend(true);
307 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
308 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
309 enabled_types_).Empty());
310 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
311 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
312 enabled_types_).Empty());
314 ConfigureDataTypes(enabled_types_,
315 Difference(syncer::ModelTypeSet::All(),
317 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
318 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
319 enabled_types_).Empty());
320 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
321 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
322 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
323 enabled_types_).Empty());
326 // Test a sync restart scenario where some types had never finished configuring.
327 // The partial types should be purged, then reconfigured properly.
328 TEST_F(SyncBackendHostTest, PartialTypes) {
329 sync_prefs_->SetSyncSetupCompleted();
330 // Set sync manager behavior before passing it down. All types have progress
331 // markers, but nigori and bookmarks are missing initial sync ended.
332 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
333 syncer::ModelTypeSet full_types =
334 Difference(enabled_types_, partial_types);
335 fake_manager_factory_->set_progress_marker_types(enabled_types_);
336 fake_manager_factory_->set_initial_sync_ended_types(full_types);
338 // Bringing up the backend should purge all partial types, then proceed to
339 // download the Nigori.
340 InitializeBackend(true);
341 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
342 syncer::ModelTypeSet(syncer::NIGORI)));
343 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
344 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
345 Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
346 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
347 enabled_types_).Equals(
348 Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
350 // Now do the actual configuration, which should download and apply bookmarks.
351 ConfigureDataTypes(enabled_types_,
352 Difference(syncer::ModelTypeSet::All(),
354 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
355 enabled_types_).Empty());
356 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
358 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
359 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
360 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
361 enabled_types_).Empty());
364 // Test the behavior when we lose the sync db. Although we already have types
365 // enabled, we should re-download all of them because we lost their data.
366 TEST_F(SyncBackendHostTest, LostDB) {
367 sync_prefs_->SetSyncSetupCompleted();
368 // Initialization should fetch the Nigori node. Everything else should be
370 InitializeBackend(true);
371 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
372 syncer::ModelTypeSet(syncer::ControlTypes())));
373 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
374 syncer::ModelTypeSet(syncer::ControlTypes())));
375 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
376 enabled_types_).Equals(
377 Difference(enabled_types_, syncer::ControlTypes())));
379 // The database was empty, so any cleaning is entirely optional. We want to
380 // reset this value before running the next part of the test, though.
381 fake_manager_->GetAndResetCleanedTypes();
383 // The actual configuration should redownload and apply all the enabled types.
384 ConfigureDataTypes(enabled_types_,
385 Difference(syncer::ModelTypeSet::All(),
387 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
388 Difference(enabled_types_, syncer::ControlTypes())));
389 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
390 enabled_types_).Empty());
391 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
392 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
393 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
394 enabled_types_).Empty());
397 TEST_F(SyncBackendHostTest, DisableTypes) {
398 // Simulate first time sync.
399 InitializeBackend(true);
400 fake_manager_->GetAndResetCleanedTypes();
401 ConfigureDataTypes(enabled_types_,
402 Difference(syncer::ModelTypeSet::All(),
404 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
406 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
407 enabled_types_).Empty());
408 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
409 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
410 enabled_types_).Empty());
412 // Then disable two datatypes.
413 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
414 syncer::SEARCH_ENGINES);
415 syncer::ModelTypeSet old_types = enabled_types_;
416 enabled_types_.RemoveAll(disabled_types);
417 ConfigureDataTypes(enabled_types_,
418 Difference(syncer::ModelTypeSet::All(),
421 // Only those datatypes disabled should be cleaned. Nothing should be
423 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
424 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
425 old_types).Equals(disabled_types));
426 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
427 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
428 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
429 enabled_types_).Empty());
432 TEST_F(SyncBackendHostTest, AddTypes) {
433 // Simulate first time sync.
434 InitializeBackend(true);
435 fake_manager_->GetAndResetCleanedTypes();
436 ConfigureDataTypes(enabled_types_,
437 Difference(syncer::ModelTypeSet::All(),
439 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
441 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
442 enabled_types_).Empty());
443 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
444 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
445 enabled_types_).Empty());
447 // Then add two datatypes.
448 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
450 enabled_types_.PutAll(new_types);
451 ConfigureDataTypes(enabled_types_,
452 Difference(syncer::ModelTypeSet::All(),
455 // Only those datatypes added should be downloaded (plus nigori). Nothing
456 // should be cleaned aside from the disabled types.
457 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
458 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
459 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
460 enabled_types_).Empty());
461 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
462 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
463 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
464 enabled_types_).Empty());
467 // And and disable in the same configuration.
468 TEST_F(SyncBackendHostTest, AddDisableTypes) {
469 // Simulate first time sync.
470 InitializeBackend(true);
471 fake_manager_->GetAndResetCleanedTypes();
472 ConfigureDataTypes(enabled_types_,
473 Difference(syncer::ModelTypeSet::All(),
475 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
477 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
478 enabled_types_).Empty());
479 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
480 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
481 enabled_types_).Empty());
483 // Then add two datatypes.
484 syncer::ModelTypeSet old_types = enabled_types_;
485 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
486 syncer::SEARCH_ENGINES);
487 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
489 enabled_types_.PutAll(new_types);
490 enabled_types_.RemoveAll(disabled_types);
491 ConfigureDataTypes(enabled_types_,
492 Difference(syncer::ModelTypeSet::All(),
495 // Only those datatypes added should be downloaded (plus nigori). Nothing
496 // should be cleaned aside from the disabled types.
497 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
498 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
499 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
500 old_types).Equals(disabled_types));
501 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
502 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
503 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
504 old_types).Equals(disabled_types));
507 // Test restarting the browser to newly supported datatypes. The new datatypes
508 // should be downloaded on the configuration after backend initialization.
509 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
510 sync_prefs_->SetSyncSetupCompleted();
511 // Set sync manager behavior before passing it down. All types have progress
512 // markers and initial sync ended except the new types.
513 syncer::ModelTypeSet old_types = enabled_types_;
514 fake_manager_factory_->set_progress_marker_types(old_types);
515 fake_manager_factory_->set_initial_sync_ended_types(old_types);
516 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
517 syncer::EXTENSION_SETTINGS);
518 enabled_types_.PutAll(new_types);
521 InitializeBackend(true);
522 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
523 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
525 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
526 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
527 enabled_types_).Equals(new_types));
529 // Downloads and applies the new types.
530 ConfigureDataTypes(enabled_types_,
531 Difference(syncer::ModelTypeSet::All(),
533 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
534 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
535 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
536 enabled_types_).Empty());
537 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
538 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
539 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
540 enabled_types_).Empty());
543 // Test the newly supported types scenario, but with the presence of partial
544 // types as well. Both partial and newly supported types should be downloaded
545 // the configuration.
546 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
547 sync_prefs_->SetSyncSetupCompleted();
548 // Set sync manager behavior before passing it down. All types have progress
549 // markers and initial sync ended except the new types.
550 syncer::ModelTypeSet old_types = enabled_types_;
551 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
552 syncer::ModelTypeSet full_types =
553 Difference(enabled_types_, partial_types);
554 fake_manager_factory_->set_progress_marker_types(old_types);
555 fake_manager_factory_->set_initial_sync_ended_types(full_types);
556 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
557 syncer::EXTENSION_SETTINGS);
558 enabled_types_.PutAll(new_types);
560 // Purge the partial types. The nigori will be among the purged types, but
561 // the syncer will re-download it by the time the initialization is complete.
562 InitializeBackend(true);
563 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
564 syncer::ModelTypeSet(syncer::NIGORI)));
565 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
566 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
567 syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
568 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
569 enabled_types_).Equals(Union(new_types, Difference(
570 partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
572 // Downloads and applies the new types and partial types (which includes
574 ConfigureDataTypes(enabled_types_,
575 Difference(syncer::ModelTypeSet::All(),
577 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
578 Union(new_types, partial_types)));
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 // Ensure the device info tracker is initialized properly on startup.
588 TEST_F(SyncBackendHostTest, InitializeDeviceInfo) {
589 ASSERT_EQ(NULL, backend_->GetSyncedDeviceTracker());
591 InitializeBackend(true);
592 const SyncedDeviceTracker* device_tracker =
593 backend_->GetSyncedDeviceTracker();
594 ASSERT_TRUE(device_tracker->ReadLocalDeviceInfo());
597 // Verify that downloading control types only downloads those types that do
598 // not have initial sync ended set.
599 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
600 sync_prefs_->SetSyncSetupCompleted();
601 // Set sync manager behavior before passing it down. Experiments and device
602 // info are new types without progress markers or initial sync ended, while
603 // all other types have been fully downloaded and applied.
604 syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::DEVICE_INFO);
605 syncer::ModelTypeSet old_types =
606 Difference(enabled_types_, new_types);
607 fake_manager_factory_->set_progress_marker_types(old_types);
608 fake_manager_factory_->set_initial_sync_ended_types(old_types);
610 // Bringing up the backend should download the new types without downloading
612 InitializeBackend(true);
613 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
614 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
615 Difference(syncer::ModelTypeSet::All(),
617 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
618 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
619 enabled_types_).Empty());
622 // Fail to download control types. It's believed that there is a server bug
623 // which can allow this to happen (crbug.com/164288). The sync backend host
624 // should detect this condition and fail to initialize the backend.
626 // The failure is "silent" in the sense that the GetUpdates request appears to
627 // be successful, but it returned no results. This means that the usual
628 // download retry logic will not be invoked.
629 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
630 fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
631 InitializeBackend(false);
634 // Test that local refresh requests are delivered to sync.
635 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
636 InitializeBackend(true);
638 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
639 IssueRefreshRequest(set1);
640 fake_manager_->WaitForSyncThread();
641 EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
643 syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
644 IssueRefreshRequest(set2);
645 fake_manager_->WaitForSyncThread();
646 EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
649 // Test that local invalidations issued before sync is initialized are ignored.
650 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
651 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
652 IssueRefreshRequest(set1);
654 InitializeBackend(true);
656 fake_manager_->WaitForSyncThread();
657 EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
660 // Test that local invalidations issued while sync is shutting down are ignored.
661 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
662 InitializeBackend(true);
664 backend_->StopSyncingForShutdown();
666 syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
667 IssueRefreshRequest(types);
668 fake_manager_->WaitForSyncThread();
669 EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
671 backend_->Shutdown(SyncBackendHost::STOP);
675 // Test that configuration on signin sends the proper GU source.
676 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
677 InitializeBackend(true);
678 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
679 fake_manager_->GetAndResetConfigureReason());
682 // Test that configuration on restart sends the proper GU source.
683 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
684 sync_prefs_->SetSyncSetupCompleted();
685 fake_manager_factory_->set_progress_marker_types(enabled_types_);
686 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
687 InitializeBackend(true);
688 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
689 fake_manager_->GetAndResetConfigureReason());
692 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
693 // setup hasn't been completed. This test ensures that cleanup happens.
694 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) {
695 const char* nonsense = "slon";
696 base::FilePath temp_directory =
697 profile_->GetPath().AppendASCII("Sync Data");
698 base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3");
699 ASSERT_TRUE(base::CreateDirectory(temp_directory));
700 ASSERT_NE(-1, file_util::WriteFile(sync_file, nonsense, strlen(nonsense)));
702 InitializeBackend(true);
704 EXPECT_FALSE(base::PathExists(sync_file));
709 } // namespace browser_sync