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