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/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 (at) 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
    778