Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / sync_backend_host_impl_unittest.cc
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.
4
5 #include "chrome/browser/sync/glue/sync_backend_host_impl.h"
6
7 #include <cstddef>
8
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"
48 #include "url/gurl.h"
49
50 using content::BrowserThread;
51 using syncer::FakeSyncManager;
52 using syncer::SyncManager;
53 using ::testing::InvokeWithoutArgs;
54 using ::testing::StrictMock;
55 using ::testing::_;
56
57 namespace browser_sync {
58
59 namespace {
60
61 const char kTestProfileName[] = "test-profile";
62
63 static const base::FilePath::CharType kTestSyncDir[] =
64     FILE_PATH_LITERAL("sync-test");
65
66 ACTION_P(Signal, event) {
67   event->Signal();
68 }
69
70 void QuitMessageLoop() {
71   base::MessageLoop::current()->Quit();
72 }
73
74 class MockSyncFrontend : public SyncFrontend {
75  public:
76   virtual ~MockSyncFrontend() {}
77
78   MOCK_METHOD3(
79       OnBackendInitialized,
80       void(const syncer::WeakHandle<syncer::JsBackend>&,
81            const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&,
82            bool));
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());
108 };
109
110 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
111  public:
112   explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager)
113      : SyncManagerFactory(NORMAL),
114        fake_manager_(fake_manager) {
115     *fake_manager_ = NULL;
116   }
117   virtual ~FakeSyncManagerFactory() {}
118
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_);
126   }
127
128   void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
129     initial_sync_ended_types_ = types;
130   }
131
132   void set_progress_marker_types(syncer::ModelTypeSet types) {
133     progress_marker_types_ = types;
134   }
135
136   void set_configure_fail_types(syncer::ModelTypeSet types) {
137     configure_fail_types_ = types;
138   }
139
140  private:
141   syncer::ModelTypeSet initial_sync_ended_types_;
142   syncer::ModelTypeSet progress_marker_types_;
143   syncer::ModelTypeSet configure_fail_types_;
144   FakeSyncManager** fake_manager_;
145 };
146
147 class SyncBackendHostTest : public testing::Test {
148  protected:
149   SyncBackendHostTest()
150       : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
151         profile_manager_(TestingBrowserProcess::GetGlobal()),
152         fake_manager_(NULL) {}
153
154   virtual ~SyncBackendHostTest() {}
155
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(),
162         profile_,
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";
169
170     fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
171
172     // These types are always implicitly enabled.
173     enabled_types_.PutAll(syncer::ControlTypes());
174
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);
185
186     network_resources_.reset(new syncer::HttpBridgeNetworkResources());
187   }
188
189   virtual void TearDown() OVERRIDE {
190     if (backend_) {
191       backend_->StopSyncingForShutdown();
192       backend_->Shutdown(SyncBackendHost::STOP);
193     }
194     backend_.reset();
195     sync_prefs_.reset();
196     profile_ = NULL;
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();
204   }
205
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(
211         &mock_frontend_,
212         scoped_ptr<base::Thread>(),
213         syncer::WeakHandle<syncer::JsEventHandler>(),
214         GURL(std::string()),
215         credentials_,
216         true,
217         fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
218         scoped_ptr<syncer::UnrecoverableErrorHandler>(
219             new syncer::TestUnrecoverableErrorHandler).Pass(),
220         NULL,
221         network_resources_.get());
222     base::RunLoop run_loop;
223     BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
224                                    run_loop.QuitClosure(),
225                                    TestTimeouts::action_timeout());
226     run_loop.Run();
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_);
231   }
232
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,
239         types_to_add,
240         &config_state_map);
241     BackendDataTypeConfigurer::SetDataTypesState(
242         BackendDataTypeConfigurer::DISABLED,
243         types_to_remove, &config_state_map);
244
245     types_to_add.PutAll(syncer::ControlTypes());
246     backend_->ConfigureDataTypes(
247         syncer::CONFIGURE_REASON_RECONFIGURATION,
248         config_state_map,
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());
257     run_loop.Run();
258   }
259
260   void IssueRefreshRequest(syncer::ModelTypeSet types) {
261     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
262
263     content::NotificationService::current()->Notify(
264         chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
265         content::Source<Profile>(profile_),
266         content::Details<syncer::ModelTypeSet>(&types));
267   }
268
269  protected:
270   void DownloadReady(syncer::ModelTypeSet succeeded_types,
271                      syncer::ModelTypeSet failed_types) {
272     base::MessageLoop::current()->Quit();
273   }
274
275   void OnDownloadRetry() {
276     NOTIMPLEMENTED();
277   }
278
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_;
290 };
291
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());
302 }
303
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());
313
314   ConfigureDataTypes(enabled_types_,
315                      Difference(syncer::ModelTypeSet::All(),
316                                 enabled_types_));
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());
323 }
324
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());
339
340   ConfigureDataTypes(enabled_types_,
341                      Difference(syncer::ModelTypeSet::All(),
342                                 enabled_types_));
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());
350 }
351
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);
363
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))));
375
376   // Now do the actual configuration, which should download and apply bookmarks.
377   ConfigureDataTypes(enabled_types_,
378                      Difference(syncer::ModelTypeSet::All(),
379                                 enabled_types_));
380   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
381                            enabled_types_).Empty());
382   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
383       partial_types));
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());
388 }
389
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
395   // left untouched.
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())));
404
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();
408
409   // The actual configuration should redownload and apply all the enabled types.
410   ConfigureDataTypes(enabled_types_,
411                      Difference(syncer::ModelTypeSet::All(),
412                                 enabled_types_));
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());
421 }
422
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(),
429                                 enabled_types_));
430   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
431       enabled_types_));
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());
437
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(),
445                                 enabled_types_));
446
447   // Only those datatypes disabled should be cleaned. Nothing should be
448   // downloaded.
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());
456 }
457
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(),
464                                 enabled_types_));
465   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
466       enabled_types_));
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());
472
473   // Then add two datatypes.
474   syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
475                                  syncer::APPS);
476   enabled_types_.PutAll(new_types);
477   ConfigureDataTypes(enabled_types_,
478                      Difference(syncer::ModelTypeSet::All(),
479                                 enabled_types_));
480
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());
491 }
492
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(),
500                                 enabled_types_));
501   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
502       enabled_types_));
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());
508
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,
514                                  syncer::APPS);
515   enabled_types_.PutAll(new_types);
516   enabled_types_.RemoveAll(disabled_types);
517   ConfigureDataTypes(enabled_types_,
518                      Difference(syncer::ModelTypeSet::All(),
519                                 enabled_types_));
520
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));
531 }
532
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);
545
546   // Does nothing.
547   InitializeBackend(true);
548   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
549   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
550                            old_types).Empty());
551   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
552   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
553       enabled_types_).Equals(new_types));
554
555   // Downloads and applies the new types.
556   ConfigureDataTypes(enabled_types_,
557                      Difference(syncer::ModelTypeSet::All(),
558                                 enabled_types_));
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());
567 }
568
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);
585
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)))));
597
598   // Downloads and applies the new types and partial types (which includes
599   // nigori anyways).
600   ConfigureDataTypes(enabled_types_,
601                      Difference(syncer::ModelTypeSet::All(),
602                                 enabled_types_));
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());
611 }
612
613 // Ensure the device info tracker is initialized properly on startup.
614 TEST_F(SyncBackendHostTest, InitializeDeviceInfo) {
615   ASSERT_EQ(NULL, backend_->GetSyncedDeviceTracker());
616
617   InitializeBackend(true);
618   const SyncedDeviceTracker* device_tracker =
619       backend_->GetSyncedDeviceTracker();
620   ASSERT_TRUE(device_tracker->ReadLocalDeviceInfo());
621 }
622
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);
635
636   // Bringing up the backend should download the new types without downloading
637   // any old types.
638   InitializeBackend(true);
639   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
640   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
641                   Difference(syncer::ModelTypeSet::All(),
642                              enabled_types_)));
643   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
644   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
645       enabled_types_).Empty());
646 }
647
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.
651 //
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);
658 }
659
660 // Test that local refresh requests are delivered to sync.
661 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
662   InitializeBackend(true);
663
664   syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
665   IssueRefreshRequest(set1);
666   fake_manager_->WaitForSyncThread();
667   EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
668
669   syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
670   IssueRefreshRequest(set2);
671   fake_manager_->WaitForSyncThread();
672   EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
673 }
674
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);
679
680   InitializeBackend(true);
681
682   fake_manager_->WaitForSyncThread();
683   EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
684 }
685
686 // Test that local invalidations issued while sync is shutting down are ignored.
687 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
688   InitializeBackend(true);
689
690   backend_->StopSyncingForShutdown();
691
692   syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
693   IssueRefreshRequest(types);
694   fake_manager_->WaitForSyncThread();
695   EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
696
697   backend_->Shutdown(SyncBackendHost::STOP);
698   backend_.reset();
699 }
700
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());
706 }
707
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());
716 }
717
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)));
727
728   InitializeBackend(true);
729
730   EXPECT_FALSE(base::PathExists(sync_file));
731 }
732
733 }  // namespace
734
735 }  // namespace browser_sync