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