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