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