Home | History | Annotate | Download | only in glue
      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/sync_frontend.h"
     20 #include "chrome/browser/sync/glue/synced_device_tracker.h"
     21 #include "chrome/browser/sync/sync_prefs.h"
     22 #include "chrome/test/base/testing_profile.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(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 SyncBackendHostImpl(
    141         profile_->GetDebugName(),
    142         profile_.get(),
    143         sync_prefs_->AsWeakPtr()));
    144     credentials_.email = "user (at) 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     network_resources_.reset(new syncer::HttpBridgeNetworkResources());
    164   }
    165 
    166   virtual void TearDown() OVERRIDE {
    167     if (backend_) {
    168       backend_->StopSyncingForShutdown();
    169       backend_->Shutdown(SyncBackendHost::STOP);
    170     }
    171     backend_.reset();
    172     sync_prefs_.reset();
    173     profile_.reset();
    174     // Pump messages posted by the sync thread (which may end up
    175     // posting on the IO thread).
    176     base::RunLoop().RunUntilIdle();
    177     content::RunAllPendingInMessageLoop(BrowserThread::IO);
    178     // Pump any messages posted by the IO thread.
    179     base::RunLoop().RunUntilIdle();
    180   }
    181 
    182   // Synchronously initializes the backend.
    183   void InitializeBackend(bool expect_success) {
    184     EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, expect_success)).
    185         WillOnce(InvokeWithoutArgs(QuitMessageLoop));
    186     backend_->Initialize(
    187         &mock_frontend_,
    188         scoped_ptr<base::Thread>(),
    189         syncer::WeakHandle<syncer::JsEventHandler>(),
    190         GURL(std::string()),
    191         credentials_,
    192         true,
    193         fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(),
    194         scoped_ptr<syncer::UnrecoverableErrorHandler>(
    195             new syncer::TestUnrecoverableErrorHandler).Pass(),
    196         NULL,
    197         network_resources_.get());
    198     base::RunLoop run_loop;
    199     BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
    200                                    run_loop.QuitClosure(),
    201                                    TestTimeouts::action_timeout());
    202     run_loop.Run();
    203     // |fake_manager_factory_|'s fake_manager() is set on the sync
    204     // thread, but we can rely on the message loop barriers to
    205     // guarantee that we see the updated value.
    206     DCHECK(fake_manager_);
    207   }
    208 
    209   // Synchronously configures the backend's datatypes.
    210   void ConfigureDataTypes(syncer::ModelTypeSet types_to_add,
    211                           syncer::ModelTypeSet types_to_remove) {
    212     BackendDataTypeConfigurer::DataTypeConfigStateMap config_state_map;
    213     BackendDataTypeConfigurer::SetDataTypesState(
    214         BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
    215         types_to_add,
    216         &config_state_map);
    217     BackendDataTypeConfigurer::SetDataTypesState(
    218         BackendDataTypeConfigurer::DISABLED,
    219         types_to_remove, &config_state_map);
    220 
    221     types_to_add.PutAll(syncer::ControlTypes());
    222     backend_->ConfigureDataTypes(
    223         syncer::CONFIGURE_REASON_RECONFIGURATION,
    224         config_state_map,
    225         base::Bind(&SyncBackendHostTest::DownloadReady,
    226                    base::Unretained(this)),
    227         base::Bind(&SyncBackendHostTest::OnDownloadRetry,
    228                    base::Unretained(this)));
    229     base::RunLoop run_loop;
    230     BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
    231                                    run_loop.QuitClosure(),
    232                                    TestTimeouts::action_timeout());
    233     run_loop.Run();
    234   }
    235 
    236   void IssueRefreshRequest(syncer::ModelTypeSet types) {
    237     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    238 
    239     content::NotificationService::current()->Notify(
    240         chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
    241         content::Source<Profile>(profile_.get()),
    242         content::Details<syncer::ModelTypeSet>(&types));
    243   }
    244 
    245  protected:
    246   void DownloadReady(syncer::ModelTypeSet succeeded_types,
    247                      syncer::ModelTypeSet failed_types) {
    248     base::MessageLoop::current()->Quit();
    249   }
    250 
    251   void OnDownloadRetry() {
    252     NOTIMPLEMENTED();
    253   }
    254 
    255   content::TestBrowserThreadBundle thread_bundle_;
    256   StrictMock<MockSyncFrontend> mock_frontend_;
    257   syncer::SyncCredentials credentials_;
    258   scoped_ptr<TestingProfile> profile_;
    259   scoped_ptr<SyncPrefs> sync_prefs_;
    260   scoped_ptr<SyncBackendHost> backend_;
    261   scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
    262   FakeSyncManager* fake_manager_;
    263   syncer::ModelTypeSet enabled_types_;
    264   scoped_ptr<syncer::NetworkResources> network_resources_;
    265 };
    266 
    267 // Test basic initialization with no initial types (first time initialization).
    268 // Only the nigori should be configured.
    269 TEST_F(SyncBackendHostTest, InitShutdown) {
    270   InitializeBackend(true);
    271   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    272       syncer::ControlTypes()));
    273   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
    274       syncer::ControlTypes()));
    275   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    276       syncer::ControlTypes()).Empty());
    277 }
    278 
    279 // Test first time sync scenario. All types should be properly configured.
    280 TEST_F(SyncBackendHostTest, FirstTimeSync) {
    281   InitializeBackend(true);
    282   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    283       syncer::ControlTypes()));
    284   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
    285       syncer::ControlTypes()));
    286   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    287       syncer::ControlTypes()).Empty());
    288 
    289   ConfigureDataTypes(enabled_types_,
    290                      Difference(syncer::ModelTypeSet::All(),
    291                                 enabled_types_));
    292   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
    293       Difference(enabled_types_, syncer::ControlTypes())));
    294   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    295   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    296   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    297       enabled_types_).Empty());
    298 }
    299 
    300 // Test the restart after setting up sync scenario. No enabled types should be
    301 // downloaded or cleaned.
    302 TEST_F(SyncBackendHostTest, Restart) {
    303   sync_prefs_->SetSyncSetupCompleted();
    304   syncer::ModelTypeSet all_but_nigori = enabled_types_;
    305   fake_manager_factory_->set_progress_marker_types(enabled_types_);
    306   fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
    307   InitializeBackend(true);
    308   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
    309   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    310                            enabled_types_).Empty());
    311   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    312   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    313       enabled_types_).Empty());
    314 
    315   ConfigureDataTypes(enabled_types_,
    316                      Difference(syncer::ModelTypeSet::All(),
    317                                 enabled_types_));
    318   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
    319   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    320                            enabled_types_).Empty());
    321   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    322   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    323   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    324       enabled_types_).Empty());
    325 }
    326 
    327 // Test a sync restart scenario where some types had never finished configuring.
    328 // The partial types should be purged, then reconfigured properly.
    329 TEST_F(SyncBackendHostTest, PartialTypes) {
    330   sync_prefs_->SetSyncSetupCompleted();
    331   // Set sync manager behavior before passing it down. All types have progress
    332   // markers, but nigori and bookmarks are missing initial sync ended.
    333   syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
    334   syncer::ModelTypeSet full_types =
    335       Difference(enabled_types_, partial_types);
    336   fake_manager_factory_->set_progress_marker_types(enabled_types_);
    337   fake_manager_factory_->set_initial_sync_ended_types(full_types);
    338 
    339   // Bringing up the backend should purge all partial types, then proceed to
    340   // download the Nigori.
    341   InitializeBackend(true);
    342   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    343       syncer::ModelTypeSet(syncer::NIGORI)));
    344   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
    345   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
    346       Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
    347   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    348       enabled_types_).Equals(
    349           Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
    350 
    351   // Now do the actual configuration, which should download and apply bookmarks.
    352   ConfigureDataTypes(enabled_types_,
    353                      Difference(syncer::ModelTypeSet::All(),
    354                                 enabled_types_));
    355   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    356                            enabled_types_).Empty());
    357   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    358       partial_types));
    359   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    360   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    361   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    362       enabled_types_).Empty());
    363 }
    364 
    365 // Test the behavior when we lose the sync db. Although we already have types
    366 // enabled, we should re-download all of them because we lost their data.
    367 TEST_F(SyncBackendHostTest, LostDB) {
    368   sync_prefs_->SetSyncSetupCompleted();
    369   // Initialization should fetch the Nigori node.  Everything else should be
    370   // left untouched.
    371   InitializeBackend(true);
    372   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    373       syncer::ModelTypeSet(syncer::ControlTypes())));
    374   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
    375       syncer::ModelTypeSet(syncer::ControlTypes())));
    376   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    377       enabled_types_).Equals(
    378           Difference(enabled_types_, syncer::ControlTypes())));
    379 
    380   // The database was empty, so any cleaning is entirely optional.  We want to
    381   // reset this value before running the next part of the test, though.
    382   fake_manager_->GetAndResetCleanedTypes();
    383 
    384   // The actual configuration should redownload and apply all the enabled types.
    385   ConfigureDataTypes(enabled_types_,
    386                      Difference(syncer::ModelTypeSet::All(),
    387                                 enabled_types_));
    388   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
    389       Difference(enabled_types_, syncer::ControlTypes())));
    390   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    391                            enabled_types_).Empty());
    392   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    393   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    394   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    395       enabled_types_).Empty());
    396 }
    397 
    398 TEST_F(SyncBackendHostTest, DisableTypes) {
    399   // Simulate first time sync.
    400   InitializeBackend(true);
    401   fake_manager_->GetAndResetCleanedTypes();
    402   ConfigureDataTypes(enabled_types_,
    403                      Difference(syncer::ModelTypeSet::All(),
    404                                 enabled_types_));
    405   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    406       enabled_types_));
    407   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    408                            enabled_types_).Empty());
    409   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    410   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    411       enabled_types_).Empty());
    412 
    413   // Then disable two datatypes.
    414   syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
    415                                       syncer::SEARCH_ENGINES);
    416   syncer::ModelTypeSet old_types = enabled_types_;
    417   enabled_types_.RemoveAll(disabled_types);
    418   ConfigureDataTypes(enabled_types_,
    419                      Difference(syncer::ModelTypeSet::All(),
    420                                 enabled_types_));
    421 
    422   // Only those datatypes disabled should be cleaned. Nothing should be
    423   // downloaded.
    424   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
    425   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    426                            old_types).Equals(disabled_types));
    427   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    428   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    429   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    430       enabled_types_).Empty());
    431 }
    432 
    433 TEST_F(SyncBackendHostTest, AddTypes) {
    434   // Simulate first time sync.
    435   InitializeBackend(true);
    436   fake_manager_->GetAndResetCleanedTypes();
    437   ConfigureDataTypes(enabled_types_,
    438                      Difference(syncer::ModelTypeSet::All(),
    439                                 enabled_types_));
    440   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    441       enabled_types_));
    442   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    443                            enabled_types_).Empty());
    444   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    445   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    446       enabled_types_).Empty());
    447 
    448   // Then add two datatypes.
    449   syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
    450                                  syncer::APPS);
    451   enabled_types_.PutAll(new_types);
    452   ConfigureDataTypes(enabled_types_,
    453                      Difference(syncer::ModelTypeSet::All(),
    454                                 enabled_types_));
    455 
    456   // Only those datatypes added should be downloaded (plus nigori). Nothing
    457   // should be cleaned aside from the disabled types.
    458   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    459       Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
    460   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    461                            enabled_types_).Empty());
    462   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    463   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    464   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    465       enabled_types_).Empty());
    466 }
    467 
    468 // And and disable in the same configuration.
    469 TEST_F(SyncBackendHostTest, AddDisableTypes) {
    470   // Simulate first time sync.
    471   InitializeBackend(true);
    472   fake_manager_->GetAndResetCleanedTypes();
    473   ConfigureDataTypes(enabled_types_,
    474                      Difference(syncer::ModelTypeSet::All(),
    475                                 enabled_types_));
    476   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    477       enabled_types_));
    478   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    479                            enabled_types_).Empty());
    480   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    481   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    482       enabled_types_).Empty());
    483 
    484   // Then add two datatypes.
    485   syncer::ModelTypeSet old_types = enabled_types_;
    486   syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
    487                                       syncer::SEARCH_ENGINES);
    488   syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
    489                                  syncer::APPS);
    490   enabled_types_.PutAll(new_types);
    491   enabled_types_.RemoveAll(disabled_types);
    492   ConfigureDataTypes(enabled_types_,
    493                      Difference(syncer::ModelTypeSet::All(),
    494                                 enabled_types_));
    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                            old_types).Equals(disabled_types));
    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       old_types).Equals(disabled_types));
    506 }
    507 
    508 // Test restarting the browser to newly supported datatypes. The new datatypes
    509 // should be downloaded on the configuration after backend initialization.
    510 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
    511   sync_prefs_->SetSyncSetupCompleted();
    512   // Set sync manager behavior before passing it down. All types have progress
    513   // markers and initial sync ended except the new types.
    514   syncer::ModelTypeSet old_types = enabled_types_;
    515   fake_manager_factory_->set_progress_marker_types(old_types);
    516   fake_manager_factory_->set_initial_sync_ended_types(old_types);
    517   syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
    518                                  syncer::EXTENSION_SETTINGS);
    519   enabled_types_.PutAll(new_types);
    520 
    521   // Does nothing.
    522   InitializeBackend(true);
    523   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
    524   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    525                            old_types).Empty());
    526   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
    527   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    528       enabled_types_).Equals(new_types));
    529 
    530   // Downloads and applies the new types.
    531   ConfigureDataTypes(enabled_types_,
    532                      Difference(syncer::ModelTypeSet::All(),
    533                                 enabled_types_));
    534   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    535       Union(new_types, syncer::ModelTypeSet(syncer::NIGORI))));
    536   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    537                            enabled_types_).Empty());
    538   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    539   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    540   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    541       enabled_types_).Empty());
    542 }
    543 
    544 // Test the newly supported types scenario, but with the presence of partial
    545 // types as well. Both partial and newly supported types should be downloaded
    546 // the configuration.
    547 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
    548   sync_prefs_->SetSyncSetupCompleted();
    549   // Set sync manager behavior before passing it down. All types have progress
    550   // markers and initial sync ended except the new types.
    551   syncer::ModelTypeSet old_types = enabled_types_;
    552   syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
    553   syncer::ModelTypeSet full_types =
    554       Difference(enabled_types_, partial_types);
    555   fake_manager_factory_->set_progress_marker_types(old_types);
    556   fake_manager_factory_->set_initial_sync_ended_types(full_types);
    557   syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
    558                                  syncer::EXTENSION_SETTINGS);
    559   enabled_types_.PutAll(new_types);
    560 
    561   // Purge the partial types.  The nigori will be among the purged types, but
    562   // the syncer will re-download it by the time the initialization is complete.
    563   InitializeBackend(true);
    564   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    565       syncer::ModelTypeSet(syncer::NIGORI)));
    566   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
    567   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
    568       syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
    569   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    570       enabled_types_).Equals(Union(new_types, Difference(
    571                       partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
    572 
    573   // Downloads and applies the new types and partial types (which includes
    574   // nigori anyways).
    575   ConfigureDataTypes(enabled_types_,
    576                      Difference(syncer::ModelTypeSet::All(),
    577                                 enabled_types_));
    578   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
    579       Union(new_types, partial_types)));
    580   EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
    581                            enabled_types_).Empty());
    582   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    583   EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
    584   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    585       enabled_types_).Empty());
    586 }
    587 
    588 // Ensure the device info tracker is initialized properly on startup.
    589 TEST_F(SyncBackendHostTest, InitializeDeviceInfo) {
    590   ASSERT_EQ(NULL, backend_->GetSyncedDeviceTracker());
    591 
    592   InitializeBackend(true);
    593   const SyncedDeviceTracker* device_tracker =
    594       backend_->GetSyncedDeviceTracker();
    595   ASSERT_TRUE(device_tracker->ReadLocalDeviceInfo());
    596 }
    597 
    598 // Verify that downloading control types only downloads those types that do
    599 // not have initial sync ended set.
    600 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
    601   sync_prefs_->SetSyncSetupCompleted();
    602   // Set sync manager behavior before passing it down. Experiments and device
    603   // info are new types without progress markers or initial sync ended, while
    604   // all other types have been fully downloaded and applied.
    605   syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::DEVICE_INFO);
    606   syncer::ModelTypeSet old_types =
    607       Difference(enabled_types_, new_types);
    608   fake_manager_factory_->set_progress_marker_types(old_types);
    609   fake_manager_factory_->set_initial_sync_ended_types(old_types);
    610 
    611   // Bringing up the backend should download the new types without downloading
    612   // any old types.
    613   InitializeBackend(true);
    614   EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
    615   EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
    616                   Difference(syncer::ModelTypeSet::All(),
    617                              enabled_types_)));
    618   EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
    619   EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
    620       enabled_types_).Empty());
    621 }
    622 
    623 // Fail to download control types.  It's believed that there is a server bug
    624 // which can allow this to happen (crbug.com/164288).  The sync backend host
    625 // should detect this condition and fail to initialize the backend.
    626 //
    627 // The failure is "silent" in the sense that the GetUpdates request appears to
    628 // be successful, but it returned no results.  This means that the usual
    629 // download retry logic will not be invoked.
    630 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
    631   fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
    632   InitializeBackend(false);
    633 }
    634 
    635 // Test that local refresh requests are delivered to sync.
    636 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
    637   InitializeBackend(true);
    638 
    639   syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
    640   IssueRefreshRequest(set1);
    641   fake_manager_->WaitForSyncThread();
    642   EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
    643 
    644   syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
    645   IssueRefreshRequest(set2);
    646   fake_manager_->WaitForSyncThread();
    647   EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
    648 }
    649 
    650 // Test that local invalidations issued before sync is initialized are ignored.
    651 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
    652   syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
    653   IssueRefreshRequest(set1);
    654 
    655   InitializeBackend(true);
    656 
    657   fake_manager_->WaitForSyncThread();
    658   EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
    659 }
    660 
    661 // Test that local invalidations issued while sync is shutting down are ignored.
    662 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
    663   InitializeBackend(true);
    664 
    665   backend_->StopSyncingForShutdown();
    666 
    667   syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
    668   IssueRefreshRequest(types);
    669   fake_manager_->WaitForSyncThread();
    670   EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
    671 
    672   backend_->Shutdown(SyncBackendHost::STOP);
    673   backend_.reset();
    674 }
    675 
    676 // Test that configuration on signin sends the proper GU source.
    677 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
    678   InitializeBackend(true);
    679   EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
    680             fake_manager_->GetAndResetConfigureReason());
    681 }
    682 
    683 // Test that configuration on restart sends the proper GU source.
    684 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
    685   sync_prefs_->SetSyncSetupCompleted();
    686   fake_manager_factory_->set_progress_marker_types(enabled_types_);
    687   fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
    688   InitializeBackend(true);
    689   EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
    690             fake_manager_->GetAndResetConfigureReason());
    691 }
    692 
    693 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
    694 // setup hasn't been completed. This test ensures that cleanup happens.
    695 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) {
    696   const char* nonsense = "slon";
    697   base::FilePath temp_directory =
    698       profile_->GetPath().AppendASCII("Sync Data");
    699   base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3");
    700   ASSERT_TRUE(base::CreateDirectory(temp_directory));
    701   ASSERT_NE(-1, file_util::WriteFile(sync_file, nonsense, strlen(nonsense)));
    702 
    703   InitializeBackend(true);
    704 
    705   EXPECT_FALSE(base::PathExists(sync_file));
    706 }
    707 
    708 }  // namespace
    709 
    710 }  // namespace browser_sync
    711