autofill_data_type_controller_unittest.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
1// Copyright (c) 2010 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/callback.h" 8#include "base/message_loop.h" 9#include "base/ref_counted.h" 10#include "base/scoped_ptr.h" 11#include "base/synchronization/waitable_event.h" 12#include "chrome/browser/autofill/personal_data_manager.h" 13#include "chrome/browser/browser_thread.h" 14#include "chrome/browser/sync/glue/autofill_data_type_controller.h" 15#include "chrome/browser/sync/glue/change_processor_mock.h" 16#include "chrome/browser/sync/glue/model_associator_mock.h" 17#include "chrome/browser/sync/profile_sync_factory_mock.h" 18#include "chrome/browser/sync/profile_sync_service_mock.h" 19#include "chrome/browser/sync/profile_sync_test_util.h" 20#include "chrome/browser/webdata/web_data_service.h" 21#include "chrome/common/notification_source.h" 22#include "chrome/common/notification_type.h" 23#include "chrome/test/profile_mock.h" 24#include "testing/gmock/include/gmock/gmock.h" 25 26using base::WaitableEvent; 27using browser_sync::AutofillDataTypeController; 28using browser_sync::ChangeProcessorMock; 29using browser_sync::DataTypeController; 30using browser_sync::ModelAssociatorMock; 31using testing::_; 32using testing::DoAll; 33using testing::Invoke; 34using testing::Return; 35using testing::SetArgumentPointee; 36 37namespace { 38 39ACTION_P(WaitOnEvent, event) { 40 event->Wait(); 41} 42 43ACTION_P(SignalEvent, event) { 44 event->Signal(); 45} 46 47class StartCallback { 48 public: 49 MOCK_METHOD1(Run, void(DataTypeController::StartResult result)); 50}; 51 52class PersonalDataManagerMock : public PersonalDataManager { 53 public: 54 MOCK_CONST_METHOD0(IsDataLoaded, bool()); 55}; 56 57class WebDataServiceFake : public WebDataService { 58 public: 59 explicit WebDataServiceFake(bool is_database_loaded) 60 : is_database_loaded_(is_database_loaded) {} 61 62 virtual bool IsDatabaseLoaded() { 63 return is_database_loaded_; 64 } 65 private: 66 bool is_database_loaded_; 67}; 68 69class SignalEventTask : public Task { 70 public: 71 explicit SignalEventTask(WaitableEvent* done_event) 72 : done_event_(done_event) {} 73 74 virtual void Run() { 75 done_event_->Signal(); 76 } 77 78 private: 79 WaitableEvent* done_event_; 80}; 81 82class AutofillDataTypeControllerTest : public testing::Test { 83 public: 84 AutofillDataTypeControllerTest() 85 : ui_thread_(BrowserThread::UI, &message_loop_), 86 db_thread_(BrowserThread::DB) {} 87 88 virtual void SetUp() { 89 db_thread_.Start(); 90 web_data_service_ = new WebDataServiceFake(true); 91 personal_data_manager_ = new PersonalDataManagerMock(); 92 autofill_dtc_ = 93 new AutofillDataTypeController(&profile_sync_factory_, 94 &profile_, 95 &service_); 96 } 97 98 virtual void TearDown() { 99 WaitForEmptyDBMessageLoop(); 100 db_thread_.Stop(); 101 } 102 103 protected: 104 void SetStartExpectations() { 105 EXPECT_CALL(profile_, GetPersonalDataManager()). 106 WillRepeatedly(Return(personal_data_manager_.get())); 107 EXPECT_CALL(*(personal_data_manager_.get()), IsDataLoaded()). 108 WillRepeatedly(Return(true)); 109 EXPECT_CALL(profile_, GetWebDataService(_)). 110 WillOnce(Return(web_data_service_.get())); 111 } 112 113 void SetAssociateExpectations() { 114 model_associator_ = new ModelAssociatorMock(); 115 change_processor_ = new ChangeProcessorMock(); 116 EXPECT_CALL(profile_sync_factory_, 117 CreateAutofillSyncComponents(_, _, _, _)). 118 WillOnce(Return( 119 ProfileSyncFactory::SyncComponents(model_associator_, 120 change_processor_))); 121 122 EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). 123 WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true))); 124 EXPECT_CALL(*model_associator_, AssociateModels()). 125 WillRepeatedly(Return(true)); 126 EXPECT_CALL(service_, ActivateDataType(_, _)); 127 EXPECT_CALL(*change_processor_, IsRunning()).WillRepeatedly(Return(true)); 128 } 129 130 void SetStopExpectations() { 131 EXPECT_CALL(service_, DeactivateDataType(_, _)); 132 EXPECT_CALL(*model_associator_, DisassociateModels()); 133 } 134 135 void WaitForEmptyDBMessageLoop() { 136 // Run a task through the DB message loop to ensure that 137 // everything before it has been run. 138 WaitableEvent done_event(false, false); 139 BrowserThread::PostTask(BrowserThread::DB, 140 FROM_HERE, 141 new SignalEventTask(&done_event)); 142 done_event.Wait(); 143 } 144 145 MessageLoopForUI message_loop_; 146 BrowserThread ui_thread_; 147 BrowserThread db_thread_; 148 scoped_refptr<AutofillDataTypeController> autofill_dtc_; 149 ProfileSyncFactoryMock profile_sync_factory_; 150 ProfileMock profile_; 151 scoped_refptr<PersonalDataManagerMock> personal_data_manager_; 152 scoped_refptr<WebDataService> web_data_service_; 153 ProfileSyncServiceMock service_; 154 ModelAssociatorMock* model_associator_; 155 ChangeProcessorMock* change_processor_; 156 StartCallback start_callback_; 157}; 158 159TEST_F(AutofillDataTypeControllerTest, StartPDMAndWDSReady) { 160 SetStartExpectations(); 161 SetAssociateExpectations(); 162 EXPECT_EQ(DataTypeController::NOT_RUNNING, autofill_dtc_->state()); 163 EXPECT_CALL(start_callback_, Run(DataTypeController::OK)). 164 WillOnce(QuitUIMessageLoop()); 165 autofill_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); 166 MessageLoop::current()->Run(); 167 EXPECT_EQ(DataTypeController::RUNNING, autofill_dtc_->state()); 168 SetStopExpectations(); 169 autofill_dtc_->Stop(); 170 EXPECT_EQ(DataTypeController::NOT_RUNNING, autofill_dtc_->state()); 171} 172 173TEST_F(AutofillDataTypeControllerTest, AbortWhilePDMStarting) { 174 EXPECT_CALL(profile_, GetPersonalDataManager()). 175 WillRepeatedly(Return(personal_data_manager_.get())); 176 EXPECT_CALL(*(personal_data_manager_.get()), IsDataLoaded()). 177 WillRepeatedly(Return(false)); 178 autofill_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); 179 EXPECT_EQ(DataTypeController::MODEL_STARTING, autofill_dtc_->state()); 180 181 EXPECT_CALL(service_, DeactivateDataType(_, _)).Times(0); 182 EXPECT_CALL(start_callback_, Run(DataTypeController::ABORTED)); 183 autofill_dtc_->Stop(); 184 EXPECT_EQ(DataTypeController::NOT_RUNNING, autofill_dtc_->state()); 185} 186 187TEST_F(AutofillDataTypeControllerTest, AbortWhileWDSStarting) { 188 EXPECT_CALL(profile_, GetPersonalDataManager()). 189 WillRepeatedly(Return(personal_data_manager_.get())); 190 EXPECT_CALL(*(personal_data_manager_.get()), IsDataLoaded()). 191 WillRepeatedly(Return(true)); 192 scoped_refptr<WebDataServiceFake> web_data_service_not_loaded( 193 new WebDataServiceFake(false)); 194 EXPECT_CALL(profile_, GetWebDataService(_)). 195 WillOnce(Return(web_data_service_not_loaded.get())); 196 autofill_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); 197 EXPECT_EQ(DataTypeController::MODEL_STARTING, autofill_dtc_->state()); 198 199 EXPECT_CALL(service_, DeactivateDataType(_, _)).Times(0); 200 EXPECT_CALL(start_callback_, Run(DataTypeController::ABORTED)); 201 autofill_dtc_->Stop(); 202 EXPECT_EQ(DataTypeController::NOT_RUNNING, autofill_dtc_->state()); 203} 204 205TEST_F(AutofillDataTypeControllerTest, AbortWhileAssociatingNotActivated) { 206 SetStartExpectations(); 207 208 model_associator_ = new ModelAssociatorMock(); 209 change_processor_ = new ChangeProcessorMock(); 210 EXPECT_CALL(profile_sync_factory_, 211 CreateAutofillSyncComponents(_, _, _, _)). 212 WillOnce(Return( 213 ProfileSyncFactory::SyncComponents(model_associator_, 214 change_processor_))); 215 216 // Use the pause_db_thread WaitableEvent to pause the DB thread when 217 // the model association process reaches the 218 // SyncModelHasUserCreatedNodes method. This lets us call Stop() 219 // while model association is in progress. When we call Stop(), 220 // this will call the model associator's AbortAssociation() method 221 // that signals the event and lets the DB thread continue. 222 WaitableEvent pause_db_thread(false, false); 223 WaitableEvent wait_for_db_thread_pause(false, false); 224 EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). 225 WillOnce(DoAll( 226 SignalEvent(&wait_for_db_thread_pause), 227 WaitOnEvent(&pause_db_thread), 228 SetArgumentPointee<0>(true), 229 Return(false))); 230 EXPECT_CALL(*model_associator_, AbortAssociation()). 231 WillOnce(SignalEvent(&pause_db_thread)); 232 233 autofill_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); 234 wait_for_db_thread_pause.Wait(); 235 EXPECT_EQ(DataTypeController::ASSOCIATING, autofill_dtc_->state()); 236 237 EXPECT_CALL(service_, DeactivateDataType(_, _)).Times(0); 238 EXPECT_CALL(start_callback_, Run(DataTypeController::ABORTED)); 239 autofill_dtc_->Stop(); 240 EXPECT_EQ(DataTypeController::NOT_RUNNING, autofill_dtc_->state()); 241} 242 243TEST_F(AutofillDataTypeControllerTest, AbortWhileAssociatingActivated) { 244 SetStartExpectations(); 245 246 model_associator_ = new ModelAssociatorMock(); 247 change_processor_ = new ChangeProcessorMock(); 248 EXPECT_CALL(profile_sync_factory_, 249 CreateAutofillSyncComponents(_, _, _, _)). 250 WillOnce(Return( 251 ProfileSyncFactory::SyncComponents(model_associator_, 252 change_processor_))); 253 EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). 254 WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true))); 255 EXPECT_CALL(*model_associator_, AssociateModels()). 256 WillRepeatedly(Return(true)); 257 EXPECT_CALL(*change_processor_, IsRunning()).WillRepeatedly(Return(true)); 258 259 // The usage of pause_db_thread is similar as in the previous test, 260 // but here we will wait until the DB thread calls 261 // ActivateDataType() before allowing it to continue. 262 WaitableEvent pause_db_thread(false, false); 263 WaitableEvent wait_for_db_thread_pause(false, false); 264 EXPECT_CALL(service_, ActivateDataType(_, _)). 265 WillOnce(DoAll( 266 SignalEvent(&wait_for_db_thread_pause), 267 WaitOnEvent(&pause_db_thread))); 268 EXPECT_CALL(*model_associator_, AbortAssociation()). 269 WillOnce(SignalEvent(&pause_db_thread)); 270 271 autofill_dtc_->Start(NewCallback(&start_callback_, &StartCallback::Run)); 272 wait_for_db_thread_pause.Wait(); 273 EXPECT_EQ(DataTypeController::ASSOCIATING, autofill_dtc_->state()); 274 275 SetStopExpectations(); 276 EXPECT_CALL(start_callback_, Run(DataTypeController::ABORTED)); 277 autofill_dtc_->Stop(); 278 EXPECT_EQ(DataTypeController::NOT_RUNNING, autofill_dtc_->state()); 279} 280 281} // namespace 282