Home | History | Annotate | Download | only in sync
      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 "base/basictypes.h"
      6 #include "base/command_line.h"
      7 #include "base/compiler_specific.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/run_loop.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "base/values.h"
     13 #include "chrome/browser/invalidation/fake_invalidation_service.h"
     14 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
     15 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
     16 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
     17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     18 #include "chrome/browser/signin/signin_manager_factory.h"
     19 #include "chrome/browser/sync/glue/sync_backend_host_mock.h"
     20 #include "chrome/browser/sync/managed_user_signin_manager_wrapper.h"
     21 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
     22 #include "chrome/common/chrome_switches.h"
     23 #include "chrome/common/pref_names.h"
     24 #include "chrome/test/base/testing_browser_process.h"
     25 #include "chrome/test/base/testing_pref_service_syncable.h"
     26 #include "chrome/test/base/testing_profile.h"
     27 #include "chrome/test/base/testing_profile_manager.h"
     28 #include "components/invalidation/invalidation_service.h"
     29 #include "components/invalidation/profile_invalidation_provider.h"
     30 #include "components/signin/core/browser/signin_manager.h"
     31 #include "components/sync_driver/data_type_manager_impl.h"
     32 #include "components/sync_driver/pref_names.h"
     33 #include "components/sync_driver/sync_prefs.h"
     34 #include "content/public/test/test_browser_thread_bundle.h"
     35 #include "google_apis/gaia/gaia_constants.h"
     36 #include "testing/gmock/include/gmock/gmock.h"
     37 #include "testing/gtest/include/gtest/gtest.h"
     38 
     39 namespace content {
     40 class BrowserContext;
     41 }
     42 
     43 namespace browser_sync {
     44 
     45 namespace {
     46 
     47 ACTION(ReturnNewDataTypeManager) {
     48   return new browser_sync::DataTypeManagerImpl(base::Closure(),
     49                                                arg0,
     50                                                arg1,
     51                                                arg2,
     52                                                arg3,
     53                                                arg4,
     54                                                arg5);
     55 }
     56 
     57 using testing::Return;
     58 using testing::StrictMock;
     59 using testing::_;
     60 
     61 class TestProfileSyncServiceObserver : public ProfileSyncServiceObserver {
     62  public:
     63   explicit TestProfileSyncServiceObserver(ProfileSyncService* service)
     64       : service_(service), first_setup_in_progress_(false) {}
     65   virtual void OnStateChanged() OVERRIDE {
     66     first_setup_in_progress_ = service_->FirstSetupInProgress();
     67   }
     68   bool first_setup_in_progress() const { return first_setup_in_progress_; }
     69  private:
     70   ProfileSyncService* service_;
     71   bool first_setup_in_progress_;
     72 };
     73 
     74 // A variant of the SyncBackendHostMock that won't automatically
     75 // call back when asked to initialized.  Allows us to test things
     76 // that could happen while backend init is in progress.
     77 class SyncBackendHostNoReturn : public SyncBackendHostMock {
     78   virtual void Initialize(
     79       SyncFrontend* frontend,
     80       scoped_ptr<base::Thread> sync_thread,
     81       const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
     82       const GURL& service_url,
     83       const syncer::SyncCredentials& credentials,
     84       bool delete_sync_data_folder,
     85       scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
     86       scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
     87       syncer::ReportUnrecoverableErrorFunction
     88           report_unrecoverable_error_function,
     89       syncer::NetworkResources* network_resources) OVERRIDE {}
     90 };
     91 
     92 class SyncBackendHostMockCollectDeleteDirParam : public SyncBackendHostMock {
     93  public:
     94   explicit SyncBackendHostMockCollectDeleteDirParam(
     95       std::vector<bool>* delete_dir_param)
     96      : delete_dir_param_(delete_dir_param) {}
     97 
     98   virtual void Initialize(
     99       SyncFrontend* frontend,
    100       scoped_ptr<base::Thread> sync_thread,
    101       const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
    102       const GURL& service_url,
    103       const syncer::SyncCredentials& credentials,
    104       bool delete_sync_data_folder,
    105       scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
    106       scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
    107       syncer::ReportUnrecoverableErrorFunction
    108           report_unrecoverable_error_function,
    109       syncer::NetworkResources* network_resources) OVERRIDE {
    110     delete_dir_param_->push_back(delete_sync_data_folder);
    111     SyncBackendHostMock::Initialize(frontend, sync_thread.Pass(),
    112                                     event_handler, service_url, credentials,
    113                                     delete_sync_data_folder,
    114                                     sync_manager_factory.Pass(),
    115                                     unrecoverable_error_handler.Pass(),
    116                                     report_unrecoverable_error_function,
    117                                     network_resources);
    118   }
    119 
    120  private:
    121   std::vector<bool>* delete_dir_param_;
    122 };
    123 
    124 ACTION(ReturnNewSyncBackendHostMock) {
    125   return new browser_sync::SyncBackendHostMock();
    126 }
    127 
    128 ACTION(ReturnNewSyncBackendHostNoReturn) {
    129   return new browser_sync::SyncBackendHostNoReturn();
    130 }
    131 
    132 ACTION_P(ReturnNewMockHostCollectDeleteDirParam, delete_dir_param) {
    133   return new browser_sync::SyncBackendHostMockCollectDeleteDirParam(
    134       delete_dir_param);
    135 }
    136 
    137 KeyedService* BuildFakeProfileInvalidationProvider(
    138     content::BrowserContext* context) {
    139   return new invalidation::ProfileInvalidationProvider(
    140       scoped_ptr<invalidation::InvalidationService>(
    141           new invalidation::FakeInvalidationService));
    142 }
    143 
    144 // A test harness that uses a real ProfileSyncService and in most cases a
    145 // MockSyncBackendHost.
    146 //
    147 // This is useful if we want to test the ProfileSyncService and don't care about
    148 // testing the SyncBackendHost.
    149 class ProfileSyncServiceTest : public ::testing::Test {
    150  protected:
    151   ProfileSyncServiceTest()
    152       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
    153         profile_manager_(TestingBrowserProcess::GetGlobal()) {}
    154   virtual ~ProfileSyncServiceTest() {}
    155 
    156   virtual void SetUp() OVERRIDE {
    157     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
    158         switches::kSyncDeferredStartupTimeoutSeconds, "0");
    159 
    160     CHECK(profile_manager_.SetUp());
    161 
    162     TestingProfile::TestingFactories testing_facotries;
    163     testing_facotries.push_back(
    164             std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
    165                            BuildAutoIssuingFakeProfileOAuth2TokenService));
    166     testing_facotries.push_back(
    167             std::make_pair(
    168                 invalidation::ProfileInvalidationProviderFactory::GetInstance(),
    169                 BuildFakeProfileInvalidationProvider));
    170 
    171     profile_ = profile_manager_.CreateTestingProfile(
    172         "sync-service-test", scoped_ptr<PrefServiceSyncable>(),
    173         base::UTF8ToUTF16("sync-service-test"), 0, std::string(),
    174         testing_facotries);
    175   }
    176 
    177   virtual void TearDown() OVERRIDE {
    178     // Kill the service before the profile.
    179     if (service_)
    180       service_->Shutdown();
    181 
    182     service_.reset();
    183   }
    184 
    185   void IssueTestTokens() {
    186     ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
    187         ->UpdateCredentials("test", "oauth2_login_token");
    188   }
    189 
    190   void CreateService(ProfileSyncServiceStartBehavior behavior) {
    191     SigninManagerBase* signin =
    192         SigninManagerFactory::GetForProfile(profile_);
    193     signin->SetAuthenticatedUsername("test");
    194     ProfileOAuth2TokenService* oauth2_token_service =
    195         ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
    196     components_factory_ = new StrictMock<ProfileSyncComponentsFactoryMock>();
    197     service_.reset(new ProfileSyncService(
    198         components_factory_,
    199         profile_,
    200         make_scoped_ptr(new ManagedUserSigninManagerWrapper(profile_, signin)),
    201         oauth2_token_service,
    202         behavior));
    203     service_->SetClearingBrowseringDataForTesting(
    204         base::Bind(&ProfileSyncServiceTest::ClearBrowsingDataCallback,
    205                    base::Unretained(this)));
    206   }
    207 
    208 #if defined(OS_WIN) || defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
    209   void CreateServiceWithoutSignIn() {
    210     CreateService(browser_sync::MANUAL_START);
    211     SigninManagerFactory::GetForProfile(profile())->SignOut(
    212         signin_metrics::SIGNOUT_TEST);
    213     service()->SetBackupStartDelayForTest(
    214         base::TimeDelta::FromMilliseconds(100));
    215   }
    216 #endif
    217 
    218   void ShutdownAndDeleteService() {
    219     if (service_)
    220       service_->Shutdown();
    221     service_.reset();
    222   }
    223 
    224   void Initialize() {
    225     service_->Initialize();
    226   }
    227 
    228   void ExpectDataTypeManagerCreation(int times) {
    229     EXPECT_CALL(*components_factory_, CreateDataTypeManager(_, _, _, _, _, _))
    230         .Times(times)
    231         .WillRepeatedly(ReturnNewDataTypeManager());
    232   }
    233 
    234   void ExpectSyncBackendHostCreation(int times) {
    235     EXPECT_CALL(*components_factory_, CreateSyncBackendHost(_, _, _, _, _))
    236         .Times(times)
    237         .WillRepeatedly(ReturnNewSyncBackendHostMock());
    238   }
    239 
    240   void ExpectSyncBackendHostCreationCollectDeleteDir(
    241       int times, std::vector<bool> *delete_dir_param) {
    242     EXPECT_CALL(*components_factory_, CreateSyncBackendHost(_, _, _, _, _))
    243         .Times(times)
    244         .WillRepeatedly(ReturnNewMockHostCollectDeleteDirParam(
    245             delete_dir_param));
    246   }
    247 
    248   void PrepareDelayedInitSyncBackendHost() {
    249     EXPECT_CALL(*components_factory_, CreateSyncBackendHost(_, _, _, _, _)).
    250         WillOnce(ReturnNewSyncBackendHostNoReturn());
    251   }
    252 
    253   TestingProfile* profile() {
    254     return profile_;
    255   }
    256 
    257   ProfileSyncService* service() {
    258     return service_.get();
    259   }
    260 
    261   ProfileSyncComponentsFactoryMock* components_factory() {
    262     return components_factory_;
    263   }
    264 
    265   void ClearBrowsingDataCallback(Profile* profile, base::Time start,
    266                                  base::Time end) {
    267     EXPECT_EQ(profile_, profile);
    268     clear_browsing_data_start_ = start;
    269   }
    270 
    271  protected:
    272   // The requested start time when ClearBrowsingDataCallback is called.
    273   base::Time clear_browsing_data_start_;
    274 
    275  private:
    276   content::TestBrowserThreadBundle thread_bundle_;
    277   TestingProfileManager profile_manager_;
    278   TestingProfile* profile_;
    279   scoped_ptr<ProfileSyncService> service_;
    280 
    281   // Pointer to the components factory.  Not owned.  May be null.
    282   ProfileSyncComponentsFactoryMock* components_factory_;
    283 };
    284 
    285 // Verify that the server URLs are sane.
    286 TEST_F(ProfileSyncServiceTest, InitialState) {
    287   CreateService(browser_sync::AUTO_START);
    288   Initialize();
    289   const std::string& url = service()->sync_service_url().spec();
    290   EXPECT_TRUE(url == ProfileSyncService::kSyncServerUrl ||
    291               url == ProfileSyncService::kDevServerUrl);
    292 }
    293 
    294 // Verify a successful initialization.
    295 TEST_F(ProfileSyncServiceTest, SuccessfulInitialization) {
    296   profile()->GetTestingPrefService()->SetManagedPref(
    297       sync_driver::prefs::kSyncManaged, base::Value::CreateBooleanValue(false));
    298   IssueTestTokens();
    299   CreateService(browser_sync::AUTO_START);
    300   ExpectDataTypeManagerCreation(1);
    301   ExpectSyncBackendHostCreation(1);
    302   Initialize();
    303   EXPECT_FALSE(service()->IsManaged());
    304   EXPECT_TRUE(service()->sync_initialized());
    305   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
    306 }
    307 
    308 
    309 // Verify that the SetSetupInProgress function call updates state
    310 // and notifies observers.
    311 TEST_F(ProfileSyncServiceTest, SetupInProgress) {
    312   CreateService(browser_sync::AUTO_START);
    313   Initialize();
    314 
    315   TestProfileSyncServiceObserver observer(service());
    316   service()->AddObserver(&observer);
    317 
    318   service()->SetSetupInProgress(true);
    319   EXPECT_TRUE(observer.first_setup_in_progress());
    320   service()->SetSetupInProgress(false);
    321   EXPECT_FALSE(observer.first_setup_in_progress());
    322 
    323   service()->RemoveObserver(&observer);
    324 }
    325 
    326 // Verify that disable by enterprise policy works.
    327 TEST_F(ProfileSyncServiceTest, DisabledByPolicyBeforeInit) {
    328   profile()->GetTestingPrefService()->SetManagedPref(
    329       sync_driver::prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
    330   IssueTestTokens();
    331   CreateService(browser_sync::AUTO_START);
    332   Initialize();
    333   EXPECT_TRUE(service()->IsManaged());
    334   EXPECT_FALSE(service()->sync_initialized());
    335 }
    336 
    337 // Verify that disable by enterprise policy works even after the backend has
    338 // been initialized.
    339 TEST_F(ProfileSyncServiceTest, DisabledByPolicyAfterInit) {
    340   IssueTestTokens();
    341   CreateService(browser_sync::AUTO_START);
    342   ExpectDataTypeManagerCreation(1);
    343   ExpectSyncBackendHostCreation(1);
    344   Initialize();
    345 
    346   EXPECT_FALSE(service()->IsManaged());
    347   EXPECT_TRUE(service()->sync_initialized());
    348 
    349   profile()->GetTestingPrefService()->SetManagedPref(
    350       sync_driver::prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
    351 
    352   EXPECT_TRUE(service()->IsManaged());
    353   EXPECT_FALSE(service()->sync_initialized());
    354 }
    355 
    356 // Exercies the ProfileSyncService's code paths related to getting shut down
    357 // before the backend initialize call returns.
    358 TEST_F(ProfileSyncServiceTest, AbortedByShutdown) {
    359   CreateService(browser_sync::AUTO_START);
    360   PrepareDelayedInitSyncBackendHost();
    361 
    362   IssueTestTokens();
    363   Initialize();
    364   EXPECT_FALSE(service()->sync_initialized());
    365 
    366   ShutdownAndDeleteService();
    367 }
    368 
    369 // Test StopAndSuppress() before we've initialized the backend.
    370 TEST_F(ProfileSyncServiceTest, EarlyStopAndSuppress) {
    371   CreateService(browser_sync::AUTO_START);
    372   IssueTestTokens();
    373 
    374   service()->StopAndSuppress();
    375   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
    376       sync_driver::prefs::kSyncSuppressStart));
    377 
    378   // Because of supression, this should fail.
    379   Initialize();
    380   EXPECT_FALSE(service()->sync_initialized());
    381 
    382   // Remove suppression.  This should be enough to allow init to happen.
    383   ExpectDataTypeManagerCreation(1);
    384   ExpectSyncBackendHostCreation(1);
    385   service()->UnsuppressAndStart();
    386   EXPECT_TRUE(service()->sync_initialized());
    387   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
    388       sync_driver::prefs::kSyncSuppressStart));
    389 }
    390 
    391 // Test StopAndSuppress() after we've initialized the backend.
    392 TEST_F(ProfileSyncServiceTest, DisableAndEnableSyncTemporarily) {
    393   CreateService(browser_sync::AUTO_START);
    394   IssueTestTokens();
    395   ExpectDataTypeManagerCreation(1);
    396   ExpectSyncBackendHostCreation(1);
    397   Initialize();
    398 
    399   EXPECT_TRUE(service()->sync_initialized());
    400   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
    401       sync_driver::prefs::kSyncSuppressStart));
    402 
    403   testing::Mock::VerifyAndClearExpectations(components_factory());
    404 
    405   service()->StopAndSuppress();
    406   EXPECT_FALSE(service()->sync_initialized());
    407   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
    408       sync_driver::prefs::kSyncSuppressStart));
    409 
    410   ExpectDataTypeManagerCreation(1);
    411   ExpectSyncBackendHostCreation(1);
    412 
    413   service()->UnsuppressAndStart();
    414   EXPECT_TRUE(service()->sync_initialized());
    415   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
    416       sync_driver::prefs::kSyncSuppressStart));
    417 }
    418 
    419 // Certain ProfileSyncService tests don't apply to Chrome OS, for example
    420 // things that deal with concepts like "signing out" and policy.
    421 #if defined(OS_WIN) || defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
    422 TEST_F(ProfileSyncServiceTest, EnableSyncAndSignOutDesktop) {
    423   CreateService(browser_sync::AUTO_START);
    424   ExpectDataTypeManagerCreation(2);
    425   ExpectSyncBackendHostCreation(2);
    426   IssueTestTokens();
    427   Initialize();
    428 
    429   EXPECT_TRUE(service()->sync_initialized());
    430   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
    431       sync_driver::prefs::kSyncSuppressStart));
    432   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
    433 
    434   SigninManagerFactory::GetForProfile(profile())->SignOut(
    435       signin_metrics::SIGNOUT_TEST);
    436   EXPECT_TRUE(service()->sync_initialized());
    437   EXPECT_EQ(ProfileSyncService::BACKUP, service()->backend_mode());
    438 }
    439 #elif !defined (OS_CHROMEOS)
    440 TEST_F(ProfileSyncServiceTest, EnableSyncAndSignOut) {
    441   CreateService(browser_sync::AUTO_START);
    442   ExpectDataTypeManagerCreation(1);
    443   ExpectSyncBackendHostCreation(1);
    444   IssueTestTokens();
    445   Initialize();
    446 
    447   EXPECT_TRUE(service()->sync_initialized());
    448   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
    449       sync_driver::prefs::kSyncSuppressStart));
    450 
    451   SigninManagerFactory::GetForProfile(profile())->SignOut(
    452       signin_metrics::SIGNOUT_TEST);
    453   EXPECT_FALSE(service()->sync_initialized());
    454 }
    455 #endif  // !defined(OS_CHROMEOS)
    456 
    457 TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) {
    458   CreateService(browser_sync::AUTO_START);
    459   IssueTestTokens();
    460   ExpectDataTypeManagerCreation(1);
    461   ExpectSyncBackendHostCreation(1);
    462   Initialize();
    463 
    464   // Initial status.
    465   ProfileSyncService::SyncTokenStatus token_status =
    466       service()->GetSyncTokenStatus();
    467   EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status);
    468   EXPECT_TRUE(token_status.connection_status_update_time.is_null());
    469   EXPECT_TRUE(token_status.token_request_time.is_null());
    470   EXPECT_TRUE(token_status.token_receive_time.is_null());
    471 
    472   // Simulate an auth error.
    473   service()->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR);
    474 
    475   // The token request will take the form of a posted task.  Run it.
    476   base::RunLoop loop;
    477   loop.RunUntilIdle();
    478 
    479   token_status = service()->GetSyncTokenStatus();
    480   EXPECT_EQ(syncer::CONNECTION_AUTH_ERROR, token_status.connection_status);
    481   EXPECT_FALSE(token_status.connection_status_update_time.is_null());
    482   EXPECT_FALSE(token_status.token_request_time.is_null());
    483   EXPECT_FALSE(token_status.token_receive_time.is_null());
    484   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
    485             token_status.last_get_token_error);
    486   EXPECT_TRUE(token_status.next_token_request_time.is_null());
    487 
    488   // Simulate successful connection.
    489   service()->OnConnectionStatusChange(syncer::CONNECTION_OK);
    490   token_status = service()->GetSyncTokenStatus();
    491   EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status);
    492 }
    493 
    494 #if defined(ENABLE_PRE_SYNC_BACKUP)
    495 TEST_F(ProfileSyncServiceTest, StartBackup) {
    496   CreateServiceWithoutSignIn();
    497   ExpectDataTypeManagerCreation(1);
    498   std::vector<bool> delete_dir_param;
    499   ExpectSyncBackendHostCreationCollectDeleteDir(1, &delete_dir_param);
    500   Initialize();
    501   EXPECT_EQ(ProfileSyncService::IDLE, service()->backend_mode());
    502   base::RunLoop run_loop;
    503   base::MessageLoop::current()->PostDelayedTask(
    504       FROM_HERE, run_loop.QuitClosure(),
    505       base::TimeDelta::FromMilliseconds(100));
    506   run_loop.Run();
    507   EXPECT_EQ(ProfileSyncService::BACKUP, service()->backend_mode());
    508 
    509   EXPECT_EQ(1u, delete_dir_param.size());
    510   EXPECT_FALSE(delete_dir_param[0]);
    511 }
    512 
    513 TEST_F(ProfileSyncServiceTest, BackupAfterSyncDisabled) {
    514   CreateService(browser_sync::MANUAL_START);
    515   service()->SetSyncSetupCompleted();
    516   ExpectDataTypeManagerCreation(2);
    517   std::vector<bool> delete_dir_param;
    518   ExpectSyncBackendHostCreationCollectDeleteDir(2, &delete_dir_param);
    519   IssueTestTokens();
    520   Initialize();
    521   EXPECT_TRUE(service()->sync_initialized());
    522   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
    523 
    524   // First sync time should be recorded.
    525   sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
    526   EXPECT_FALSE(sync_prefs.GetFirstSyncTime().is_null());
    527 
    528   syncer::SyncProtocolError client_cmd;
    529   client_cmd.action = syncer::DISABLE_SYNC_ON_CLIENT;
    530   service()->OnActionableError(client_cmd);
    531   EXPECT_EQ(ProfileSyncService::BACKUP, service()->backend_mode());
    532 
    533   // Browsing data is not cleared because rollback is skipped.
    534   EXPECT_TRUE(clear_browsing_data_start_.is_null());
    535 
    536   // First sync time is erased once backup starts.
    537   EXPECT_TRUE(sync_prefs.GetFirstSyncTime().is_null());
    538 
    539   EXPECT_EQ(2u, delete_dir_param.size());
    540   EXPECT_FALSE(delete_dir_param[0]);
    541   EXPECT_TRUE(delete_dir_param[1]);
    542 }
    543 
    544 TEST_F(ProfileSyncServiceTest, RollbackThenBackup) {
    545   CommandLine::ForCurrentProcess()->AppendSwitch(
    546       switches::kSyncEnableRollback);
    547 
    548   CreateService(browser_sync::MANUAL_START);
    549   service()->SetSyncSetupCompleted();
    550   ExpectDataTypeManagerCreation(3);
    551   std::vector<bool> delete_dir_param;
    552   ExpectSyncBackendHostCreationCollectDeleteDir(3, &delete_dir_param);
    553   IssueTestTokens();
    554   Initialize();
    555   EXPECT_TRUE(service()->sync_initialized());
    556   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
    557 
    558   // First sync time should be recorded.
    559   sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
    560   base::Time first_sync_time = sync_prefs.GetFirstSyncTime();
    561   EXPECT_FALSE(first_sync_time.is_null());
    562 
    563   syncer::SyncProtocolError client_cmd;
    564   client_cmd.action = syncer::DISABLE_SYNC_AND_ROLLBACK;
    565   service()->OnActionableError(client_cmd);
    566   EXPECT_TRUE(service()->sync_initialized());
    567   EXPECT_EQ(ProfileSyncService::ROLLBACK, service()->backend_mode());
    568 
    569   // Browser data should be cleared during rollback.
    570   EXPECT_EQ(first_sync_time, clear_browsing_data_start_);
    571 
    572   client_cmd.action = syncer::ROLLBACK_DONE;
    573   service()->OnActionableError(client_cmd);
    574   EXPECT_TRUE(service()->sync_initialized());
    575   EXPECT_EQ(ProfileSyncService::BACKUP, service()->backend_mode());
    576 
    577   // First sync time is erased once backup starts.
    578   EXPECT_TRUE(sync_prefs.GetFirstSyncTime().is_null());
    579 
    580   EXPECT_EQ(3u, delete_dir_param.size());
    581   EXPECT_FALSE(delete_dir_param[0]);
    582   EXPECT_FALSE(delete_dir_param[1]);
    583   EXPECT_TRUE(delete_dir_param[2]);
    584 }
    585 
    586 TEST_F(ProfileSyncServiceTest, StartNewBackupDbOnSettingsReset) {
    587   CreateServiceWithoutSignIn();
    588   ExpectDataTypeManagerCreation(1);
    589   std::vector<bool> delete_dir_param;
    590   ExpectSyncBackendHostCreationCollectDeleteDir(1, &delete_dir_param);
    591   Initialize();
    592   EXPECT_EQ(ProfileSyncService::IDLE, service()->backend_mode());
    593 
    594   // Set reset time to pretend settings reset happened.
    595   profile()->GetPrefs()->SetString(
    596       prefs::kPreferenceResetTime,
    597       base::Int64ToString(base::Time::Now().ToInternalValue()));
    598 
    599   base::RunLoop run_loop;
    600   base::MessageLoop::current()->PostDelayedTask(
    601       FROM_HERE, run_loop.QuitClosure(),
    602       base::TimeDelta::FromMilliseconds(100));
    603   run_loop.Run();
    604 
    605   EXPECT_EQ(ProfileSyncService::BACKUP, service()->backend_mode());
    606 
    607   EXPECT_EQ(1u, delete_dir_param.size());
    608   EXPECT_TRUE(delete_dir_param[0]);
    609 }
    610 
    611 #endif
    612 
    613 TEST_F(ProfileSyncServiceTest, GetSyncServiceURL) {
    614   // See that we can override the URL with a flag.
    615   CommandLine command_line(
    616       base::FilePath(base::FilePath(FILE_PATH_LITERAL("chrome.exe"))));
    617   command_line.AppendSwitchASCII(switches::kSyncServiceURL, "https://foo/bar");
    618   EXPECT_EQ("https://foo/bar",
    619             ProfileSyncService::GetSyncServiceURL(command_line).spec());
    620 }
    621 
    622 }  // namespace
    623 }  // namespace browser_sync
    624