Home | History | Annotate | Download | only in sync
      1 // Copyright (c) 2011 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 "testing/gtest/include/gtest/gtest.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/message_loop.h"
      9 #include "chrome/browser/net/gaia/token_service.h"
     10 #include "chrome/browser/prefs/pref_service.h"
     11 #include "chrome/browser/sync/glue/data_type_manager.h"
     12 #include "chrome/browser/sync/glue/data_type_manager_mock.h"
     13 #include "chrome/browser/sync/profile_sync_factory_mock.h"
     14 #include "chrome/browser/sync/profile_sync_test_util.h"
     15 #include "chrome/browser/sync/test_profile_sync_service.h"
     16 #include "chrome/common/net/gaia/gaia_auth_consumer.h"
     17 #include "chrome/common/net/gaia/gaia_constants.h"
     18 #include "chrome/common/pref_names.h"
     19 #include "chrome/test/testing_profile.h"
     20 #include "content/browser/browser_thread.h"
     21 #include "content/common/notification_type.h"
     22 #include "testing/gmock/include/gmock/gmock.h"
     23 
     24 using browser_sync::DataTypeManager;
     25 using browser_sync::DataTypeManagerMock;
     26 using testing::_;
     27 using testing::AnyNumber;
     28 using testing::DoAll;
     29 using testing::InvokeArgument;
     30 using testing::Mock;
     31 using testing::Return;
     32 
     33 ACTION_P(InvokeCallback, callback_result) {
     34   arg0->Run(callback_result);
     35   delete arg0;
     36 }
     37 
     38 // TODO(skrul) This test fails on the mac. See http://crbug.com/33443
     39 #if defined(OS_MACOSX)
     40 #define SKIP_MACOSX(test) DISABLED_##test
     41 #else
     42 #define SKIP_MACOSX(test) test
     43 #endif
     44 
     45 // TODO(chron): Test not using cros_user flag and use signin_
     46 class ProfileSyncServiceStartupTest : public testing::Test {
     47  public:
     48   ProfileSyncServiceStartupTest()
     49       : ui_thread_(BrowserThread::UI, &message_loop_) {}
     50 
     51   virtual ~ProfileSyncServiceStartupTest() {
     52     // The PSS has some deletes that are scheduled on the main thread
     53     // so we must delete the service and run the message loop.
     54     service_.reset();
     55     MessageLoop::current()->RunAllPending();
     56   }
     57 
     58   virtual void SetUp() {
     59     profile_.CreateRequestContext();
     60     service_.reset(new TestProfileSyncService(&factory_, &profile_,
     61                                               "test", true, NULL));
     62     service_->AddObserver(&observer_);
     63     service_->set_synchronous_sync_configuration();
     64   }
     65 
     66   virtual void TearDown() {
     67     service_->RemoveObserver(&observer_);
     68     {
     69       // The request context gets deleted on the I/O thread. To prevent a leak
     70       // supply one here.
     71       BrowserThread io_thread(BrowserThread::IO, MessageLoop::current());
     72       profile_.ResetRequestContext();
     73     }
     74     MessageLoop::current()->RunAllPending();
     75   }
     76 
     77  protected:
     78   DataTypeManagerMock* SetUpDataTypeManager() {
     79     DataTypeManagerMock* data_type_manager = new DataTypeManagerMock();
     80     EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).
     81         WillOnce(Return(data_type_manager));
     82     return data_type_manager;
     83   }
     84 
     85   MessageLoop message_loop_;
     86   BrowserThread ui_thread_;
     87   TestingProfile profile_;
     88   ProfileSyncFactoryMock factory_;
     89   scoped_ptr<TestProfileSyncService> service_;
     90   ProfileSyncServiceObserverMock observer_;
     91 };
     92 
     93 TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(StartFirstTime)) {
     94   DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
     95   EXPECT_CALL(*data_type_manager, Configure(_)).Times(0);
     96 
     97   // We've never completed startup.
     98   profile_.GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted);
     99 
    100   // Should not actually start, rather just clean things up and wait
    101   // to be enabled.
    102   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    103   service_->Initialize();
    104 
    105   // Preferences should be back to defaults.
    106   EXPECT_EQ(0, profile_.GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime));
    107   EXPECT_FALSE(profile_.GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted));
    108   Mock::VerifyAndClearExpectations(data_type_manager);
    109 
    110   // Then start things up.
    111   EXPECT_CALL(*data_type_manager, Configure(_)).Times(3);
    112   EXPECT_CALL(*data_type_manager, state()).
    113       WillOnce(Return(DataTypeManager::CONFIGURED));
    114   EXPECT_CALL(*data_type_manager, Stop()).Times(1);
    115   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    116 
    117   // Create some tokens in the token service; the service will startup when
    118   // it is notified that tokens are available.
    119   profile_.GetTokenService()->IssueAuthTokenForTest(
    120       GaiaConstants::kSyncService, "sync_token");
    121 
    122   syncable::ModelTypeSet set;
    123   set.insert(syncable::BOOKMARKS);
    124   service_->OnUserChoseDatatypes(false, set);
    125 }
    126 
    127 TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(StartNormal)) {
    128   DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
    129   EXPECT_CALL(*data_type_manager, Configure(_)).Times(2);
    130   EXPECT_CALL(*data_type_manager, state()).
    131       WillOnce(Return(DataTypeManager::CONFIGURED));
    132   EXPECT_CALL(*data_type_manager, Stop()).Times(1);
    133 
    134   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    135 
    136   // Pre load the tokens
    137   profile_.GetTokenService()->IssueAuthTokenForTest(
    138       GaiaConstants::kSyncService, "sync_token");
    139   service_->Initialize();
    140 }
    141 
    142 TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(ManagedStartup)) {
    143   // Disable sync through policy.
    144   profile_.GetPrefs()->SetBoolean(prefs::kSyncManaged, true);
    145 
    146   EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).Times(0);
    147   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    148 
    149   // Service should not be started by Initialize() since it's managed.
    150   profile_.GetTokenService()->IssueAuthTokenForTest(
    151       GaiaConstants::kSyncService, "sync_token");
    152   service_->Initialize();
    153 }
    154 
    155 TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(SwitchManaged)) {
    156   DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
    157   EXPECT_CALL(*data_type_manager, Configure(_)).Times(2);
    158   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    159 
    160   profile_.GetTokenService()->IssueAuthTokenForTest(
    161       GaiaConstants::kSyncService, "sync_token");
    162   service_->Initialize();
    163 
    164   // The service should stop when switching to managed mode.
    165   Mock::VerifyAndClearExpectations(data_type_manager);
    166   EXPECT_CALL(*data_type_manager, state()).
    167       WillOnce(Return(DataTypeManager::CONFIGURED));
    168   EXPECT_CALL(*data_type_manager, Stop()).Times(1);
    169   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    170   profile_.GetPrefs()->SetBoolean(prefs::kSyncManaged, true);
    171 
    172   // When switching back to unmanaged, the state should change, but the service
    173   // should not start up automatically (kSyncSetupCompleted will be false).
    174   Mock::VerifyAndClearExpectations(data_type_manager);
    175   EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).Times(0);
    176   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    177   profile_.GetPrefs()->ClearPref(prefs::kSyncManaged);
    178 }
    179 
    180 TEST_F(ProfileSyncServiceStartupTest, ClearServerData) {
    181   DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
    182   EXPECT_CALL(*data_type_manager, Configure(_)).Times(2);
    183   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    184 
    185   profile_.GetTokenService()->IssueAuthTokenForTest(
    186       GaiaConstants::kSyncService, "sync_token");
    187   service_->Initialize();
    188   Mock::VerifyAndClearExpectations(data_type_manager);
    189 
    190   // Success can overwrite failure, failure cannot overwrite success.  We want
    191   // this behavior because once clear has succeeded, sync gets disabled, and
    192   // we don't care about any subsequent failures (e.g. timeouts)
    193   service_->ResetClearServerDataState();
    194   EXPECT_TRUE(ProfileSyncService::CLEAR_NOT_STARTED ==
    195       service_->GetClearServerDataState());
    196 
    197   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    198   service_->OnClearServerDataFailed();
    199   EXPECT_TRUE(ProfileSyncService::CLEAR_FAILED ==
    200       service_->GetClearServerDataState());
    201 
    202   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    203   service_->OnClearServerDataSucceeded();
    204   EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED ==
    205       service_->GetClearServerDataState());
    206 
    207   service_->OnClearServerDataFailed();
    208   EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED ==
    209       service_->GetClearServerDataState());
    210 
    211   // Now test the timeout states
    212   service_->ResetClearServerDataState();
    213   EXPECT_TRUE(ProfileSyncService::CLEAR_NOT_STARTED ==
    214       service_->GetClearServerDataState());
    215 
    216   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    217   service_->OnClearServerDataTimeout();
    218   EXPECT_TRUE(ProfileSyncService::CLEAR_FAILED ==
    219       service_->GetClearServerDataState());
    220 
    221   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    222   service_->OnClearServerDataSucceeded();
    223   EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED ==
    224       service_->GetClearServerDataState());
    225 
    226   service_->OnClearServerDataFailed();
    227   EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED ==
    228       service_->GetClearServerDataState());
    229 
    230   // Test the pending state, doesn't matter what state
    231   // the back end syncmgr returns
    232   EXPECT_CALL(*data_type_manager, state()).
    233     WillOnce(Return(DataTypeManager::STOPPED));
    234   service_->ResetClearServerDataState();
    235   service_->ClearServerData();
    236   EXPECT_TRUE(ProfileSyncService::CLEAR_CLEARING ==
    237       service_->GetClearServerDataState());
    238 
    239   // Stop the timer and reset the state
    240   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    241   service_->OnClearServerDataSucceeded();
    242   service_->ResetClearServerDataState();
    243 }
    244 
    245 TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(StartFailure)) {
    246   DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
    247   DataTypeManager::ConfigureResult configure_result =
    248       DataTypeManager::ASSOCIATION_FAILED;
    249   browser_sync::DataTypeManager::ConfigureResultWithErrorLocation result(
    250       configure_result, FROM_HERE, syncable::ModelTypeSet());
    251   EXPECT_CALL(*data_type_manager, Configure(_)).
    252       WillRepeatedly(DoAll(NotifyFromDataTypeManager(data_type_manager,
    253                          NotificationType::SYNC_CONFIGURE_START),
    254                      NotifyFromDataTypeManagerWithResult(data_type_manager,
    255                          NotificationType::SYNC_CONFIGURE_DONE,
    256                          &result)));
    257   EXPECT_CALL(*data_type_manager, state()).
    258       WillOnce(Return(DataTypeManager::STOPPED));
    259 
    260   EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
    261 
    262   profile_.GetTokenService()->IssueAuthTokenForTest(
    263       GaiaConstants::kSyncService, "sync_token");
    264   service_->Initialize();
    265   EXPECT_TRUE(service_->unrecoverable_error_detected());
    266 }
    267