Upstream version 5.34.104.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/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"
42 #include "url/gurl.h"
43
44 using content::BrowserThread;
45 using syncer::FakeSyncManager;
46 using syncer::SyncManager;
47 using ::testing::InvokeWithoutArgs;
48 using ::testing::StrictMock;
49 using ::testing::_;
50
51 namespace browser_sync {
52
53 namespace {
54
55 ACTION_P(Signal, event) {
56   event->Signal();
57 }
58
59 void QuitMessageLoop() {
60   base::MessageLoop::current()->Quit();
61 }
62
63 class MockSyncFrontend : public SyncFrontend {
64  public:
65   virtual ~MockSyncFrontend() {}
66
67   MOCK_METHOD3(
68       OnBackendInitialized,
69       void(const syncer::WeakHandle<syncer::JsBackend>&,
70            const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&,
71            bool));
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());
90 };
91
92 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
93  public:
94   explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager)
95      : fake_manager_(fake_manager) {
96     *fake_manager_ = NULL;
97   }
98   virtual ~FakeSyncManagerFactory() {}
99
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_);
107   }
108
109   void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
110     initial_sync_ended_types_ = types;
111   }
112
113   void set_progress_marker_types(syncer::ModelTypeSet types) {
114     progress_marker_types_ = types;
115   }
116
117   void set_configure_fail_types(syncer::ModelTypeSet types) {
118     configure_fail_types_ = types;
119   }
120
121  private:
122   syncer::ModelTypeSet initial_sync_ended_types_;
123   syncer::ModelTypeSet progress_marker_types_;
124   syncer::ModelTypeSet configure_fail_types_;
125   FakeSyncManager** fake_manager_;
126 };
127
128 class SyncBackendHostTest : public testing::Test {
129  protected:
130   SyncBackendHostTest()
131       : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
132         fake_manager_(NULL) {}
133
134   virtual ~SyncBackendHostTest() {}
135
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(),
141         profile_.get(),
142         sync_prefs_->AsWeakPtr()));
143     credentials_.email = "user@example.com";
144     credentials_.sync_token = "sync_token";
145
146     fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
147
148     // These types are always implicitly enabled.
149     enabled_types_.PutAll(syncer::ControlTypes());
150
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);
161
162     network_resources_.reset(new syncer::HttpBridgeNetworkResources());
163   }
164
165   virtual void TearDown() OVERRIDE {
166     if (backend_) {
167       backend_->StopSyncingForShutdown();
168       backend_->Shutdown(SyncBackendHost::STOP);
169     }
170     backend_.reset();
171     sync_prefs_.reset();
172     profile_.reset();
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();
179   }
180
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(
186         &mock_frontend_,
187         scoped_ptr<base::Thread>(),
188         syncer::WeakHandle<syncer::JsEventHandler>(),
189         GURL(std::string()),
190         credentials_,
191         true,
192         fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
193         scoped_ptr<syncer::UnrecoverableErrorHandler>(
194             new syncer::TestUnrecoverableErrorHandler).Pass(),
195         NULL,
196         network_resources_.get());
197     base::RunLoop run_loop;
198     BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
199                                    run_loop.QuitClosure(),
200                                    TestTimeouts::action_timeout());
201     run_loop.Run();
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_);
206   }
207
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,
214         types_to_add,
215         &config_state_map);
216     BackendDataTypeConfigurer::SetDataTypesState(
217         BackendDataTypeConfigurer::DISABLED,
218         types_to_remove, &config_state_map);
219
220     types_to_add.PutAll(syncer::ControlTypes());
221     backend_->ConfigureDataTypes(
222         syncer::CONFIGURE_REASON_RECONFIGURATION,
223         config_state_map,
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());
232     run_loop.Run();
233   }
234
235   void IssueRefreshRequest(syncer::ModelTypeSet types) {
236     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
237
238     content::NotificationService::current()->Notify(
239         chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
240         content::Source<Profile>(profile_.get()),
241         content::Details<syncer::ModelTypeSet>(&types));
242   }
243
244  protected:
245   void DownloadReady(syncer::ModelTypeSet succeeded_types,
246                      syncer::ModelTypeSet failed_types) {
247     base::MessageLoop::current()->Quit();
248   }
249
250   void OnDownloadRetry() {
251     NOTIMPLEMENTED();
252   }
253
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_;
264 };
265
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());
276 }
277
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());
287
288   ConfigureDataTypes(enabled_types_,
289                      Difference(syncer::ModelTypeSet::All(),
290                                 enabled_types_));
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());
297 }
298
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());
313
314   ConfigureDataTypes(enabled_types_,
315                      Difference(syncer::ModelTypeSet::All(),
316                                 enabled_types_));
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());
324 }
325
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);
337
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))));
349
350   // Now do the actual configuration, which should download and apply bookmarks.
351   ConfigureDataTypes(enabled_types_,
352                      Difference(syncer::ModelTypeSet::All(),
353                                 enabled_types_));
354   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
355                            enabled_types_).Empty());
356   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
357       partial_types));
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());
362 }
363
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
369   // left untouched.
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())));
378
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();
382
383   // The actual configuration should redownload and apply all the enabled types.
384   ConfigureDataTypes(enabled_types_,
385                      Difference(syncer::ModelTypeSet::All(),
386                                 enabled_types_));
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());
395 }
396
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(),
403                                 enabled_types_));
404   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
405       enabled_types_));
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());
411
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(),
419                                 enabled_types_));
420
421   // Only those datatypes disabled should be cleaned. Nothing should be
422   // downloaded.
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());
430 }
431
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(),
438                                 enabled_types_));
439   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
440       enabled_types_));
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());
446
447   // Then add two datatypes.
448   syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
449                                  syncer::APPS);
450   enabled_types_.PutAll(new_types);
451   ConfigureDataTypes(enabled_types_,
452                      Difference(syncer::ModelTypeSet::All(),
453                                 enabled_types_));
454
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());
465 }
466
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(),
474                                 enabled_types_));
475   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
476       enabled_types_));
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());
482
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,
488                                  syncer::APPS);
489   enabled_types_.PutAll(new_types);
490   enabled_types_.RemoveAll(disabled_types);
491   ConfigureDataTypes(enabled_types_,
492                      Difference(syncer::ModelTypeSet::All(),
493                                 enabled_types_));
494
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));
505 }
506
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);
519
520   // Does nothing.
521   InitializeBackend(true);
522   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
523   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
524                            old_types).Empty());
525   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
526   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
527       enabled_types_).Equals(new_types));
528
529   // Downloads and applies the new types.
530   ConfigureDataTypes(enabled_types_,
531                      Difference(syncer::ModelTypeSet::All(),
532                                 enabled_types_));
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());
541 }
542
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);
559
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)))));
571
572   // Downloads and applies the new types and partial types (which includes
573   // nigori anyways).
574   ConfigureDataTypes(enabled_types_,
575                      Difference(syncer::ModelTypeSet::All(),
576                                 enabled_types_));
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());
585 }
586
587 // Ensure the device info tracker is initialized properly on startup.
588 TEST_F(SyncBackendHostTest, InitializeDeviceInfo) {
589   ASSERT_EQ(NULL, backend_->GetSyncedDeviceTracker());
590
591   InitializeBackend(true);
592   const SyncedDeviceTracker* device_tracker =
593       backend_->GetSyncedDeviceTracker();
594   ASSERT_TRUE(device_tracker->ReadLocalDeviceInfo());
595 }
596
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);
609
610   // Bringing up the backend should download the new types without downloading
611   // any old types.
612   InitializeBackend(true);
613   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
614   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
615                   Difference(syncer::ModelTypeSet::All(),
616                              enabled_types_)));
617   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
618   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
619       enabled_types_).Empty());
620 }
621
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.
625 //
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);
632 }
633
634 // Test that local refresh requests are delivered to sync.
635 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
636   InitializeBackend(true);
637
638   syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
639   IssueRefreshRequest(set1);
640   fake_manager_->WaitForSyncThread();
641   EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
642
643   syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
644   IssueRefreshRequest(set2);
645   fake_manager_->WaitForSyncThread();
646   EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
647 }
648
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);
653
654   InitializeBackend(true);
655
656   fake_manager_->WaitForSyncThread();
657   EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
658 }
659
660 // Test that local invalidations issued while sync is shutting down are ignored.
661 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
662   InitializeBackend(true);
663
664   backend_->StopSyncingForShutdown();
665
666   syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
667   IssueRefreshRequest(types);
668   fake_manager_->WaitForSyncThread();
669   EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
670
671   backend_->Shutdown(SyncBackendHost::STOP);
672   backend_.reset();
673 }
674
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());
680 }
681
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());
690 }
691
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)));
701
702   InitializeBackend(true);
703
704   EXPECT_FALSE(base::PathExists(sync_file));
705 }
706
707 }  // namespace
708
709 }  // namespace browser_sync