Upstream version 10.39.225.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/files/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/test/base/testing_browser_process.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "chrome/test/base/testing_profile_manager.h"
21 #include "components/invalidation/invalidator_state.h"
22 #include "components/invalidation/invalidator_storage.h"
23 #include "components/invalidation/profile_invalidation_provider.h"
24 #include "components/sync_driver/device_info.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 "google_apis/gaia/gaia_constants.h"
32 #include "net/url_request/test_url_fetcher_factory.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 sync_driver::SyncFrontend {
75  public:
76   virtual ~MockSyncFrontend() {}
77
78   MOCK_METHOD4(
79       OnBackendInitialized,
80       void(const syncer::WeakHandle<syncer::JsBackend>&,
81            const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&,
82            const std::string&,
83            bool));
84   MOCK_METHOD0(OnSyncCycleCompleted, void());
85   MOCK_METHOD1(OnConnectionStatusChange,
86                void(syncer::ConnectionStatus status));
87   MOCK_METHOD0(OnClearServerDataSucceeded, void());
88   MOCK_METHOD0(OnClearServerDataFailed, void());
89   MOCK_METHOD2(OnPassphraseRequired,
90                void(syncer::PassphraseRequiredReason,
91                     const sync_pb::EncryptedData&));
92   MOCK_METHOD0(OnPassphraseAccepted, void());
93   MOCK_METHOD2(OnEncryptedTypesChanged,
94                void(syncer::ModelTypeSet, bool));
95   MOCK_METHOD0(OnEncryptionComplete, void());
96   MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet));
97   MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&));
98   MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated,
99                void(syncer::ModelType, const syncer::CommitCounters&));
100   MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated,
101                void(syncer::ModelType, const syncer::UpdateCounters&));
102   MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated,
103                void(syncer::ModelType, const syncer::StatusCounters&));
104   MOCK_METHOD1(OnExperimentsChanged,
105       void(const syncer::Experiments&));
106   MOCK_METHOD1(OnActionableError,
107       void(const syncer::SyncProtocolError& sync_error));
108   MOCK_METHOD0(OnSyncConfigureRetry, void());
109 };
110
111 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
112  public:
113   explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager)
114      : SyncManagerFactory(NORMAL),
115        fake_manager_(fake_manager) {
116     *fake_manager_ = NULL;
117   }
118   virtual ~FakeSyncManagerFactory() {}
119
120   // SyncManagerFactory implementation.  Called on the sync thread.
121   virtual scoped_ptr<SyncManager> CreateSyncManager(
122       std::string name) OVERRIDE {
123     *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_,
124                                          progress_marker_types_,
125                                          configure_fail_types_);
126     return scoped_ptr<SyncManager>(*fake_manager_);
127   }
128
129   void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
130     initial_sync_ended_types_ = types;
131   }
132
133   void set_progress_marker_types(syncer::ModelTypeSet types) {
134     progress_marker_types_ = types;
135   }
136
137   void set_configure_fail_types(syncer::ModelTypeSet types) {
138     configure_fail_types_ = types;
139   }
140
141  private:
142   syncer::ModelTypeSet initial_sync_ended_types_;
143   syncer::ModelTypeSet progress_marker_types_;
144   syncer::ModelTypeSet configure_fail_types_;
145   FakeSyncManager** fake_manager_;
146 };
147
148 class SyncBackendHostTest : public testing::Test {
149  protected:
150   SyncBackendHostTest()
151       : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
152         profile_manager_(TestingBrowserProcess::GetGlobal()),
153         fake_manager_(NULL) {}
154
155   virtual ~SyncBackendHostTest() {}
156
157   virtual void SetUp() OVERRIDE {
158     ASSERT_TRUE(profile_manager_.SetUp());
159     profile_ = profile_manager_.CreateTestingProfile(kTestProfileName);
160     sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
161     backend_.reset(new SyncBackendHostImpl(
162         profile_->GetDebugName(),
163         profile_,
164         invalidation::ProfileInvalidationProviderFactory::GetForProfile(
165             profile_)->GetInvalidationService(),
166         sync_prefs_->AsWeakPtr(),
167         base::FilePath(kTestSyncDir)));
168     credentials_.email = "user@example.com";
169     credentials_.sync_token = "sync_token";
170     credentials_.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope);
171
172     fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
173
174     // These types are always implicitly enabled.
175     enabled_types_.PutAll(syncer::ControlTypes());
176
177     // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
178     // Registrar removing them if it can't find their model workers.
179     enabled_types_.Put(syncer::BOOKMARKS);
180     enabled_types_.Put(syncer::NIGORI);
181     enabled_types_.Put(syncer::DEVICE_INFO);
182     enabled_types_.Put(syncer::PREFERENCES);
183     enabled_types_.Put(syncer::SESSIONS);
184     enabled_types_.Put(syncer::SEARCH_ENGINES);
185     enabled_types_.Put(syncer::AUTOFILL);
186     enabled_types_.Put(syncer::EXPERIMENTS);
187
188     network_resources_.reset(new syncer::HttpBridgeNetworkResources());
189   }
190
191   virtual void TearDown() OVERRIDE {
192     if (backend_) {
193       backend_->StopSyncingForShutdown();
194       backend_->Shutdown(syncer::STOP_SYNC);
195     }
196     backend_.reset();
197     sync_prefs_.reset();
198     profile_ = NULL;
199     profile_manager_.DeleteTestingProfile(kTestProfileName);
200     // Pump messages posted by the sync thread (which may end up
201     // posting on the IO thread).
202     base::RunLoop().RunUntilIdle();
203     content::RunAllPendingInMessageLoop(BrowserThread::IO);
204     // Pump any messages posted by the IO thread.
205     base::RunLoop().RunUntilIdle();
206   }
207
208   // Synchronously initializes the backend.
209   void InitializeBackend(bool expect_success) {
210     EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, _, expect_success)).
211         WillOnce(InvokeWithoutArgs(QuitMessageLoop));
212     backend_->Initialize(
213         &mock_frontend_,
214         scoped_ptr<base::Thread>(),
215         syncer::WeakHandle<syncer::JsEventHandler>(),
216         GURL(std::string()),
217         credentials_,
218         true,
219         fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
220         scoped_ptr<syncer::UnrecoverableErrorHandler>(
221             new syncer::TestUnrecoverableErrorHandler).Pass(),
222         NULL,
223         network_resources_.get());
224     base::RunLoop run_loop;
225     BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
226                                    run_loop.QuitClosure(),
227                                    TestTimeouts::action_timeout());
228     run_loop.Run();
229     // |fake_manager_factory_|'s fake_manager() is set on the sync
230     // thread, but we can rely on the message loop barriers to
231     // guarantee that we see the updated value.
232     DCHECK(fake_manager_);
233   }
234
235   // Synchronously configures the backend's datatypes.
236   void ConfigureDataTypes(syncer::ModelTypeSet types_to_add,
237                           syncer::ModelTypeSet types_to_remove,
238                           syncer::ModelTypeSet types_to_unapply) {
239     sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap
240         config_state_map;
241     sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
242         sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
243         types_to_add,
244         &config_state_map);
245     sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
246         sync_driver::BackendDataTypeConfigurer::DISABLED,
247         types_to_remove, &config_state_map);
248     sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
249         sync_driver::BackendDataTypeConfigurer::UNREADY,
250         types_to_unapply, &config_state_map);
251
252     types_to_add.PutAll(syncer::ControlTypes());
253     backend_->ConfigureDataTypes(
254         syncer::CONFIGURE_REASON_RECONFIGURATION,
255         config_state_map,
256         base::Bind(&SyncBackendHostTest::DownloadReady,
257                    base::Unretained(this)),
258         base::Bind(&SyncBackendHostTest::OnDownloadRetry,
259                    base::Unretained(this)));
260     base::RunLoop run_loop;
261     BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
262                                    run_loop.QuitClosure(),
263                                    TestTimeouts::action_timeout());
264     run_loop.Run();
265   }
266
267   void IssueRefreshRequest(syncer::ModelTypeSet types) {
268     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
269
270     content::NotificationService::current()->Notify(
271         chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
272         content::Source<Profile>(profile_),
273         content::Details<syncer::ModelTypeSet>(&types));
274   }
275
276  protected:
277   void DownloadReady(syncer::ModelTypeSet succeeded_types,
278                      syncer::ModelTypeSet failed_types) {
279     base::MessageLoop::current()->Quit();
280   }
281
282   void OnDownloadRetry() {
283     NOTIMPLEMENTED();
284   }
285
286   content::TestBrowserThreadBundle thread_bundle_;
287   StrictMock<MockSyncFrontend> mock_frontend_;
288   syncer::SyncCredentials credentials_;
289   TestingProfileManager profile_manager_;
290   TestingProfile* profile_;
291   scoped_ptr<sync_driver::SyncPrefs> sync_prefs_;
292   scoped_ptr<SyncBackendHost> backend_;
293   scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
294   FakeSyncManager* fake_manager_;
295   syncer::ModelTypeSet enabled_types_;
296   scoped_ptr<syncer::NetworkResources> network_resources_;
297 };
298
299 // Test basic initialization with no initial types (first time initialization).
300 // Only the nigori should be configured.
301 TEST_F(SyncBackendHostTest, InitShutdown) {
302   InitializeBackend(true);
303   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
304       syncer::ControlTypes()));
305   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
306       syncer::ControlTypes()));
307   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
308       syncer::ControlTypes()).Empty());
309 }
310
311 // Test first time sync scenario. All types should be properly configured.
312 TEST_F(SyncBackendHostTest, FirstTimeSync) {
313   InitializeBackend(true);
314   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
315       syncer::ControlTypes()));
316   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
317       syncer::ControlTypes()));
318   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
319       syncer::ControlTypes()).Empty());
320
321   ConfigureDataTypes(enabled_types_,
322                      Difference(syncer::ModelTypeSet::All(),
323                                 enabled_types_),
324                      syncer::ModelTypeSet());
325   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
326       Difference(enabled_types_, syncer::ControlTypes())));
327   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
328   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
329   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
330       enabled_types_).Empty());
331 }
332
333 // Test the restart after setting up sync scenario. No enabled types should be
334 // downloaded or cleaned.
335 TEST_F(SyncBackendHostTest, Restart) {
336   sync_prefs_->SetSyncSetupCompleted();
337   syncer::ModelTypeSet all_but_nigori = enabled_types_;
338   fake_manager_factory_->set_progress_marker_types(enabled_types_);
339   fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
340   InitializeBackend(true);
341   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
342   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
343                            enabled_types_).Empty());
344   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
345   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
346       enabled_types_).Empty());
347
348   ConfigureDataTypes(enabled_types_,
349                      Difference(syncer::ModelTypeSet::All(),
350                                 enabled_types_),
351                      syncer::ModelTypeSet());
352   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
353   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
354                            enabled_types_).Empty());
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 a sync restart scenario where some types had never finished configuring.
362 // The partial types should be purged, then reconfigured properly.
363 TEST_F(SyncBackendHostTest, PartialTypes) {
364   sync_prefs_->SetSyncSetupCompleted();
365   // Set sync manager behavior before passing it down. All types have progress
366   // markers, but nigori and bookmarks are missing initial sync ended.
367   syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
368   syncer::ModelTypeSet full_types =
369       Difference(enabled_types_, partial_types);
370   fake_manager_factory_->set_progress_marker_types(enabled_types_);
371   fake_manager_factory_->set_initial_sync_ended_types(full_types);
372
373   // Bringing up the backend should purge all partial types, then proceed to
374   // download the Nigori.
375   InitializeBackend(true);
376   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
377       syncer::ModelTypeSet(syncer::NIGORI)));
378   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
379   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
380       Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
381   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
382       enabled_types_).Equals(
383           Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
384
385   // Now do the actual configuration, which should download and apply bookmarks.
386   ConfigureDataTypes(enabled_types_,
387                      Difference(syncer::ModelTypeSet::All(),
388                                 enabled_types_),
389                      syncer::ModelTypeSet());
390   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
391                            enabled_types_).Empty());
392   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
393       partial_types));
394   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
395   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
396   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
397       enabled_types_).Empty());
398 }
399
400 // Test the behavior when we lose the sync db. Although we already have types
401 // enabled, we should re-download all of them because we lost their data.
402 TEST_F(SyncBackendHostTest, LostDB) {
403   sync_prefs_->SetSyncSetupCompleted();
404   // Initialization should fetch the Nigori node.  Everything else should be
405   // left untouched.
406   InitializeBackend(true);
407   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
408       syncer::ModelTypeSet(syncer::ControlTypes())));
409   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
410       syncer::ModelTypeSet(syncer::ControlTypes())));
411   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
412       enabled_types_).Equals(
413           Difference(enabled_types_, syncer::ControlTypes())));
414
415   // The database was empty, so any cleaning is entirely optional.  We want to
416   // reset this value before running the next part of the test, though.
417   fake_manager_->GetAndResetCleanedTypes();
418
419   // The actual configuration should redownload and apply all the enabled types.
420   ConfigureDataTypes(enabled_types_,
421                      Difference(syncer::ModelTypeSet::All(),
422                                 enabled_types_),
423                      syncer::ModelTypeSet());
424   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
425       Difference(enabled_types_, syncer::ControlTypes())));
426   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
427                            enabled_types_).Empty());
428   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
429   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
430   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
431       enabled_types_).Empty());
432 }
433
434 TEST_F(SyncBackendHostTest, DisableTypes) {
435   // Simulate first time sync.
436   InitializeBackend(true);
437   fake_manager_->GetAndResetCleanedTypes();
438   ConfigureDataTypes(enabled_types_,
439                      Difference(syncer::ModelTypeSet::All(),
440                                 enabled_types_),
441                      syncer::ModelTypeSet());
442   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
443       enabled_types_));
444   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
445                            enabled_types_).Empty());
446   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
447   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
448       enabled_types_).Empty());
449
450   // Then disable two datatypes.
451   syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
452                                       syncer::SEARCH_ENGINES);
453   syncer::ModelTypeSet old_types = enabled_types_;
454   enabled_types_.RemoveAll(disabled_types);
455   ConfigureDataTypes(enabled_types_,
456                      Difference(syncer::ModelTypeSet::All(),
457                                 enabled_types_),
458                      syncer::ModelTypeSet());
459
460   // Only those datatypes disabled should be cleaned. Nothing should be
461   // downloaded.
462   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
463   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
464                            old_types).Equals(disabled_types));
465   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
466   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
467   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
468       enabled_types_).Empty());
469 }
470
471 TEST_F(SyncBackendHostTest, AddTypes) {
472   // Simulate first time sync.
473   InitializeBackend(true);
474   fake_manager_->GetAndResetCleanedTypes();
475   ConfigureDataTypes(enabled_types_,
476                      Difference(syncer::ModelTypeSet::All(),
477                                 enabled_types_),
478                      syncer::ModelTypeSet());
479   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
480       enabled_types_));
481   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
482                            enabled_types_).Empty());
483   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
484   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
485       enabled_types_).Empty());
486
487   // Then add two datatypes.
488   syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
489                                  syncer::APPS);
490   enabled_types_.PutAll(new_types);
491   ConfigureDataTypes(enabled_types_,
492                      Difference(syncer::ModelTypeSet::All(),
493                                 enabled_types_),
494                      syncer::ModelTypeSet());
495
496   // Only those datatypes added should be downloaded (plus nigori). Nothing
497   // should be cleaned aside from the disabled types.
498   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
499       Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
500   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
501                            enabled_types_).Empty());
502   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
503   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
504   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
505       enabled_types_).Empty());
506 }
507
508 // And and disable in the same configuration.
509 TEST_F(SyncBackendHostTest, AddDisableTypes) {
510   // Simulate first time sync.
511   InitializeBackend(true);
512   fake_manager_->GetAndResetCleanedTypes();
513   ConfigureDataTypes(enabled_types_,
514                      Difference(syncer::ModelTypeSet::All(),
515                                 enabled_types_),
516                      syncer::ModelTypeSet());
517   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
518       enabled_types_));
519   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
520                            enabled_types_).Empty());
521   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
522   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
523       enabled_types_).Empty());
524
525   // Then add two datatypes.
526   syncer::ModelTypeSet old_types = enabled_types_;
527   syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
528                                       syncer::SEARCH_ENGINES);
529   syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
530                                  syncer::APPS);
531   enabled_types_.PutAll(new_types);
532   enabled_types_.RemoveAll(disabled_types);
533   ConfigureDataTypes(enabled_types_,
534                      Difference(syncer::ModelTypeSet::All(),
535                                 enabled_types_),
536                      syncer::ModelTypeSet());
537
538   // Only those datatypes added should be downloaded (plus nigori). Nothing
539   // should be cleaned aside from the disabled types.
540   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
541       Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
542   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
543                            old_types).Equals(disabled_types));
544   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
545   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
546   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
547       old_types).Equals(disabled_types));
548 }
549
550 // Test restarting the browser to newly supported datatypes. The new datatypes
551 // should be downloaded on the configuration after backend initialization.
552 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
553   sync_prefs_->SetSyncSetupCompleted();
554   // Set sync manager behavior before passing it down. All types have progress
555   // markers and initial sync ended except the new types.
556   syncer::ModelTypeSet old_types = enabled_types_;
557   fake_manager_factory_->set_progress_marker_types(old_types);
558   fake_manager_factory_->set_initial_sync_ended_types(old_types);
559   syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
560                                  syncer::EXTENSION_SETTINGS);
561   enabled_types_.PutAll(new_types);
562
563   // Does nothing.
564   InitializeBackend(true);
565   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
566   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
567                            old_types).Empty());
568   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
569   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
570       enabled_types_).Equals(new_types));
571
572   // Downloads and applies the new types.
573   ConfigureDataTypes(enabled_types_,
574                      Difference(syncer::ModelTypeSet::All(),
575                                 enabled_types_),
576                      syncer::ModelTypeSet());
577   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
578       Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
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 // Test the newly supported types scenario, but with the presence of partial
588 // types as well. Both partial and newly supported types should be downloaded
589 // the configuration.
590 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
591   sync_prefs_->SetSyncSetupCompleted();
592   // Set sync manager behavior before passing it down. All types have progress
593   // markers and initial sync ended except the new types.
594   syncer::ModelTypeSet old_types = enabled_types_;
595   syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
596   syncer::ModelTypeSet full_types =
597       Difference(enabled_types_, partial_types);
598   fake_manager_factory_->set_progress_marker_types(old_types);
599   fake_manager_factory_->set_initial_sync_ended_types(full_types);
600   syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
601                                  syncer::EXTENSION_SETTINGS);
602   enabled_types_.PutAll(new_types);
603
604   // Purge the partial types.  The nigori will be among the purged types, but
605   // the syncer will re-download it by the time the initialization is complete.
606   InitializeBackend(true);
607   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
608       syncer::ModelTypeSet(syncer::NIGORI)));
609   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
610   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
611       syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
612   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
613       enabled_types_).Equals(Union(new_types, Difference(
614                       partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
615
616   // Downloads and applies the new types and partial types (which includes
617   // nigori anyways).
618   ConfigureDataTypes(enabled_types_,
619                      Difference(syncer::ModelTypeSet::All(),
620                                 enabled_types_),
621                      syncer::ModelTypeSet());
622   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
623       Union(new_types, partial_types)));
624   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
625                            enabled_types_).Empty());
626   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
627   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
628   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
629       enabled_types_).Empty());
630 }
631
632 // Verify that downloading control types only downloads those types that do
633 // not have initial sync ended set.
634 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
635   sync_prefs_->SetSyncSetupCompleted();
636   // Set sync manager behavior before passing it down. Experiments and device
637   // info are new types without progress markers or initial sync ended, while
638   // all other types have been fully downloaded and applied.
639   syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::NIGORI);
640   syncer::ModelTypeSet old_types =
641       Difference(enabled_types_, new_types);
642   fake_manager_factory_->set_progress_marker_types(old_types);
643   fake_manager_factory_->set_initial_sync_ended_types(old_types);
644
645   // Bringing up the backend should download the new types without downloading
646   // any old types.
647   InitializeBackend(true);
648   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
649   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
650                   Difference(syncer::ModelTypeSet::All(),
651                              enabled_types_)));
652   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
653   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
654       enabled_types_).Empty());
655 }
656
657 // Fail to download control types.  It's believed that there is a server bug
658 // which can allow this to happen (crbug.com/164288).  The sync backend host
659 // should detect this condition and fail to initialize the backend.
660 //
661 // The failure is "silent" in the sense that the GetUpdates request appears to
662 // be successful, but it returned no results.  This means that the usual
663 // download retry logic will not be invoked.
664 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
665   fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
666   InitializeBackend(false);
667 }
668
669 // Test that local refresh requests are delivered to sync.
670 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
671   InitializeBackend(true);
672
673   syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
674   IssueRefreshRequest(set1);
675   fake_manager_->WaitForSyncThread();
676   EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
677
678   syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
679   IssueRefreshRequest(set2);
680   fake_manager_->WaitForSyncThread();
681   EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
682 }
683
684 // Test that local invalidations issued before sync is initialized are ignored.
685 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
686   syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
687   IssueRefreshRequest(set1);
688
689   InitializeBackend(true);
690
691   fake_manager_->WaitForSyncThread();
692   EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
693 }
694
695 // Test that local invalidations issued while sync is shutting down are ignored.
696 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
697   InitializeBackend(true);
698
699   backend_->StopSyncingForShutdown();
700
701   syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
702   IssueRefreshRequest(types);
703   fake_manager_->WaitForSyncThread();
704   EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
705
706   backend_->Shutdown(syncer::STOP_SYNC);
707   backend_.reset();
708 }
709
710 // Test that configuration on signin sends the proper GU source.
711 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
712   InitializeBackend(true);
713   EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
714             fake_manager_->GetAndResetConfigureReason());
715 }
716
717 // Test that configuration on restart sends the proper GU source.
718 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
719   sync_prefs_->SetSyncSetupCompleted();
720   fake_manager_factory_->set_progress_marker_types(enabled_types_);
721   fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
722   InitializeBackend(true);
723   EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
724             fake_manager_->GetAndResetConfigureReason());
725 }
726
727 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
728 // setup hasn't been completed. This test ensures that cleanup happens.
729 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) {
730   const char* nonsense = "slon";
731   base::FilePath temp_directory =
732       profile_->GetPath().Append(base::FilePath(kTestSyncDir));
733   base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3");
734   ASSERT_TRUE(base::CreateDirectory(temp_directory));
735   ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense)));
736
737   InitializeBackend(true);
738
739   EXPECT_FALSE(base::PathExists(sync_file));
740 }
741
742 // If bookmarks encounter an error that results in disabling without purging
743 // (such as when the type is unready), and then is explicitly disabled, the
744 // SyncBackendHost needs to tell the manager to purge the type, even though
745 // it's already disabled (crbug.com/386778).
746 TEST_F(SyncBackendHostTest, DisableThenPurgeType) {
747   syncer::ModelTypeSet error_types(syncer::BOOKMARKS);
748
749   InitializeBackend(true);
750
751   // First enable the types.
752   ConfigureDataTypes(enabled_types_,
753                      Difference(syncer::ModelTypeSet::All(),
754                                 enabled_types_),
755                      syncer::ModelTypeSet());
756
757   // Then mark the error types as unready (disables without purging).
758   ConfigureDataTypes(enabled_types_,
759                      Difference(syncer::ModelTypeSet::All(),
760                                 enabled_types_),
761                      error_types);
762   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
763       error_types).Empty());
764
765   // Lastly explicitly disable the error types, which should result in a purge.
766   enabled_types_.RemoveAll(error_types);
767   ConfigureDataTypes(enabled_types_,
768                      Difference(syncer::ModelTypeSet::All(),
769                                 enabled_types_),
770                      syncer::ModelTypeSet());
771   EXPECT_FALSE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
772       error_types).Empty());
773 }
774
775 }  // namespace
776
777 }  // namespace browser_sync