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 <set> 6 #include <string> 7 #include <vector> 8 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/message_loop.h" 15 #include "base/string16.h" 16 #include "base/synchronization/waitable_event.h" 17 #include "base/task.h" 18 #include "base/time.h" 19 #include "base/utf_string_conversions.h" 20 #include "chrome/browser/autofill/autofill_common_test.h" 21 #include "chrome/browser/sync/abstract_profile_sync_service_test.h" 22 #include "chrome/browser/sync/engine/model_changing_syncer_command.h" 23 #include "chrome/browser/sync/engine/syncapi.h" 24 #include "chrome/browser/sync/glue/autofill_change_processor.h" 25 #include "chrome/browser/sync/glue/autofill_data_type_controller.h" 26 #include "chrome/browser/sync/glue/autofill_model_associator.h" 27 #include "chrome/browser/sync/glue/autofill_profile_change_processor.h" 28 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h" 29 #include "chrome/browser/sync/glue/autofill_profile_model_associator.h" 30 #include "chrome/browser/sync/glue/data_type_controller.h" 31 #include "chrome/browser/sync/profile_sync_factory.h" 32 #include "chrome/browser/sync/profile_sync_service.h" 33 #include "chrome/browser/sync/profile_sync_test_util.h" 34 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h" 35 #include "chrome/browser/sync/syncable/autofill_migration.h" 36 #include "chrome/browser/sync/syncable/directory_manager.h" 37 #include "chrome/browser/sync/syncable/model_type.h" 38 #include "chrome/browser/sync/syncable/syncable.h" 39 #include "chrome/browser/sync/test_profile_sync_service.h" 40 #include "chrome/browser/webdata/autofill_change.h" 41 #include "chrome/browser/webdata/autofill_entry.h" 42 #include "chrome/browser/webdata/autofill_table.h" 43 #include "chrome/browser/webdata/web_database.h" 44 #include "chrome/common/net/gaia/gaia_constants.h" 45 #include "chrome/test/profile_mock.h" 46 #include "chrome/test/sync/engine/test_id_factory.h" 47 #include "content/browser/browser_thread.h" 48 #include "content/common/notification_source.h" 49 #include "content/common/notification_type.h" 50 #include "testing/gmock/include/gmock/gmock.h" 51 52 using base::Time; 53 using base::WaitableEvent; 54 using browser_sync::AutofillChangeProcessor; 55 using browser_sync::AutofillDataTypeController; 56 using browser_sync::AutofillModelAssociator; 57 using browser_sync::AutofillProfileChangeProcessor; 58 using browser_sync::AutofillProfileDataTypeController; 59 using browser_sync::AutofillProfileModelAssociator; 60 using browser_sync::DataTypeController; 61 using browser_sync::GROUP_DB; 62 using browser_sync::kAutofillTag; 63 using browser_sync::SyncBackendHostForProfileSyncTest; 64 using browser_sync::UnrecoverableErrorHandler; 65 using syncable::CREATE_NEW_UPDATE_ITEM; 66 using syncable::AUTOFILL; 67 using syncable::BASE_VERSION; 68 using syncable::CREATE; 69 using syncable::GET_BY_SERVER_TAG; 70 using syncable::INVALID; 71 using syncable::MutableEntry; 72 using syncable::OriginalEntries; 73 using syncable::SERVER_PARENT_ID; 74 using syncable::SERVER_SPECIFICS; 75 using syncable::SPECIFICS; 76 using syncable::UNITTEST; 77 using syncable::WriterTag; 78 using syncable::WriteTransaction; 79 using testing::_; 80 using testing::DoAll; 81 using testing::DoDefault; 82 using testing::ElementsAre; 83 using testing::Eq; 84 using testing::Invoke; 85 using testing::Mock; 86 using testing::Return; 87 using testing::SaveArg; 88 using testing::SetArgumentPointee; 89 90 namespace syncable { 91 class Id; 92 } 93 94 class AutofillTableMock : public AutofillTable { 95 public: 96 AutofillTableMock() : AutofillTable(NULL, NULL) {} 97 MOCK_METHOD2(RemoveFormElement, 98 bool(const string16& name, const string16& value)); // NOLINT 99 MOCK_METHOD1(GetAllAutofillEntries, 100 bool(std::vector<AutofillEntry>* entries)); // NOLINT 101 MOCK_METHOD3(GetAutofillTimestamps, 102 bool(const string16& name, // NOLINT 103 const string16& value, 104 std::vector<base::Time>* timestamps)); 105 MOCK_METHOD1(UpdateAutofillEntries, 106 bool(const std::vector<AutofillEntry>&)); // NOLINT 107 MOCK_METHOD1(GetAutofillProfiles, 108 bool(std::vector<AutofillProfile*>*)); // NOLINT 109 MOCK_METHOD1(UpdateAutofillProfile, 110 bool(const AutofillProfile&)); // NOLINT 111 MOCK_METHOD1(AddAutofillProfile, 112 bool(const AutofillProfile&)); // NOLINT 113 MOCK_METHOD1(RemoveAutofillProfile, 114 bool(const std::string&)); // NOLINT 115 }; 116 117 class WebDatabaseFake : public WebDatabase { 118 public: 119 explicit WebDatabaseFake(AutofillTable* autofill_table) 120 : autofill_table_(autofill_table) {} 121 122 virtual AutofillTable* GetAutofillTable() { 123 return autofill_table_; 124 } 125 126 private: 127 AutofillTable* autofill_table_; 128 }; 129 130 131 class ProfileSyncServiceAutofillTest; 132 133 template<class AutofillProfile> 134 syncable::ModelType GetModelType() { 135 return syncable::UNSPECIFIED; 136 } 137 138 template<> 139 syncable::ModelType GetModelType<AutofillEntry>() { 140 return syncable::AUTOFILL; 141 } 142 143 template<> 144 syncable::ModelType GetModelType<AutofillProfile>() { 145 return syncable::AUTOFILL_PROFILE; 146 } 147 148 class WebDataServiceFake : public WebDataService { 149 public: 150 explicit WebDataServiceFake(WebDatabase* web_database) 151 : web_database_(web_database) {} 152 virtual bool IsDatabaseLoaded() { 153 return true; 154 } 155 156 virtual WebDatabase* GetDatabase() { 157 return web_database_; 158 } 159 160 private: 161 WebDatabase* web_database_; 162 }; 163 164 ACTION_P4(MakeAutofillSyncComponents, service, wd, pdm, dtc) { 165 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 166 if (!BrowserThread::CurrentlyOn(BrowserThread::DB)) 167 return ProfileSyncFactory::SyncComponents(NULL, NULL); 168 AutofillModelAssociator* model_associator = 169 new AutofillModelAssociator(service, wd, pdm); 170 AutofillChangeProcessor* change_processor = 171 new AutofillChangeProcessor(model_associator, wd, pdm, dtc); 172 return ProfileSyncFactory::SyncComponents(model_associator, 173 change_processor); 174 } 175 176 ACTION_P4(MakeAutofillProfileSyncComponents, service, wd, pdm, dtc) { 177 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 178 if (!BrowserThread::CurrentlyOn(BrowserThread::DB)) 179 return ProfileSyncFactory::SyncComponents(NULL, NULL); 180 AutofillProfileModelAssociator* model_associator = 181 new AutofillProfileModelAssociator(service, wd, pdm); 182 AutofillProfileChangeProcessor* change_processor = 183 new AutofillProfileChangeProcessor(model_associator, wd, pdm, dtc); 184 return ProfileSyncFactory::SyncComponents(model_associator, 185 change_processor); 186 } 187 188 class AbstractAutofillFactory { 189 public: 190 virtual AutofillDataTypeController* CreateDataTypeController( 191 ProfileSyncFactory *factory, 192 ProfileMock* profile, 193 ProfileSyncService* service) = 0; 194 virtual void SetExpectation(ProfileSyncFactoryMock* factory, 195 ProfileSyncService* service, 196 WebDatabase* wd, 197 PersonalDataManager* pdm, 198 DataTypeController* dtc) = 0; 199 virtual ~AbstractAutofillFactory() {} 200 }; 201 202 class AutofillEntryFactory : public AbstractAutofillFactory { 203 public: 204 browser_sync::AutofillDataTypeController* CreateDataTypeController( 205 ProfileSyncFactory *factory, 206 ProfileMock* profile, 207 ProfileSyncService* service) { 208 return new AutofillDataTypeController(factory, 209 profile, 210 service); 211 } 212 213 void SetExpectation(ProfileSyncFactoryMock* factory, 214 ProfileSyncService* service, 215 WebDatabase* wd, 216 PersonalDataManager* pdm, 217 DataTypeController* dtc) { 218 EXPECT_CALL(*factory, CreateAutofillSyncComponents(_,_,_,_)). 219 WillOnce(MakeAutofillSyncComponents(service, wd, pdm, dtc)); 220 } 221 }; 222 223 class AutofillProfileFactory : public AbstractAutofillFactory { 224 public: 225 browser_sync::AutofillDataTypeController* CreateDataTypeController( 226 ProfileSyncFactory *factory, 227 ProfileMock* profile, 228 ProfileSyncService* service) { 229 return new AutofillProfileDataTypeController(factory, 230 profile, 231 service); 232 } 233 234 void SetExpectation(ProfileSyncFactoryMock* factory, 235 ProfileSyncService* service, 236 WebDatabase* wd, 237 PersonalDataManager* pdm, 238 DataTypeController* dtc) { 239 EXPECT_CALL(*factory, CreateAutofillProfileSyncComponents(_,_,_,_)). 240 WillOnce(MakeAutofillProfileSyncComponents(service, wd, pdm, dtc)); 241 } 242 }; 243 244 class PersonalDataManagerMock: public PersonalDataManager { 245 public: 246 MOCK_CONST_METHOD0(IsDataLoaded, bool()); 247 MOCK_METHOD0(LoadProfiles, void()); 248 MOCK_METHOD0(LoadCreditCards, void()); 249 MOCK_METHOD0(Refresh, void()); 250 }; 251 template <class T> class AddAutofillTask; 252 253 class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest { 254 protected: 255 ProfileSyncServiceAutofillTest() : db_thread_(BrowserThread::DB) {} 256 257 AutofillProfileFactory profile_factory_; 258 AutofillEntryFactory entry_factory_; 259 260 AbstractAutofillFactory* GetFactory(syncable::ModelType type) { 261 if (type == syncable::AUTOFILL) { 262 return &entry_factory_; 263 } else if (type == syncable::AUTOFILL_PROFILE) { 264 return &profile_factory_; 265 } else { 266 NOTREACHED(); 267 return NULL; 268 } 269 } 270 virtual void SetUp() { 271 profile_.CreateRequestContext(); 272 web_database_.reset(new WebDatabaseFake(&autofill_table_)); 273 web_data_service_ = new WebDataServiceFake(web_database_.get()); 274 personal_data_manager_ = new PersonalDataManagerMock(); 275 EXPECT_CALL(*personal_data_manager_, LoadProfiles()).Times(1); 276 EXPECT_CALL(*personal_data_manager_, LoadCreditCards()).Times(1); 277 personal_data_manager_->Init(&profile_); 278 db_thread_.Start(); 279 280 notification_service_ = new ThreadNotificationService(&db_thread_); 281 notification_service_->Init(); 282 } 283 284 virtual void TearDown() { 285 service_.reset(); 286 notification_service_->TearDown(); 287 db_thread_.Stop(); 288 { 289 // The request context gets deleted on the I/O thread. To prevent a leak 290 // supply one here. 291 BrowserThread io_thread(BrowserThread::IO, MessageLoop::current()); 292 profile_.ResetRequestContext(); 293 } 294 MessageLoop::current()->RunAllPending(); 295 } 296 297 void StartSyncService(Task* task, 298 bool will_fail_association, 299 syncable::ModelType type) { 300 AbstractAutofillFactory* factory = GetFactory(type); 301 service_.reset( 302 new TestProfileSyncService(&factory_, &profile_, "test_user", false, 303 task)); 304 AutofillDataTypeController* data_type_controller = 305 factory->CreateDataTypeController(&factory_, 306 &profile_, 307 service_.get()); 308 SyncBackendHostForProfileSyncTest:: 309 SetDefaultExpectationsForWorkerCreation(&profile_); 310 311 factory->SetExpectation(&factory_, 312 service_.get(), 313 web_database_.get(), 314 personal_data_manager_.get(), 315 data_type_controller); 316 317 EXPECT_CALL(factory_, CreateDataTypeManager(_, _)). 318 WillOnce(ReturnNewDataTypeManager()); 319 320 EXPECT_CALL(profile_, GetWebDataService(_)). 321 WillOnce(Return(web_data_service_.get())); 322 323 EXPECT_CALL(profile_, GetPersonalDataManager()). 324 WillRepeatedly(Return(personal_data_manager_.get())); 325 326 EXPECT_CALL(*personal_data_manager_, IsDataLoaded()). 327 WillRepeatedly(Return(true)); 328 329 // We need tokens to get the tests going 330 token_service_.IssueAuthTokenForTest( 331 GaiaConstants::kSyncService, "token"); 332 333 EXPECT_CALL(profile_, GetTokenService()). 334 WillRepeatedly(Return(&token_service_)); 335 336 service_->RegisterDataTypeController(data_type_controller); 337 service_->Initialize(); 338 MessageLoop::current()->Run(); 339 } 340 341 bool AddAutofillSyncNode(const AutofillEntry& entry) { 342 sync_api::WriteTransaction trans(service_->GetUserShare()); 343 sync_api::ReadNode autofill_root(&trans); 344 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag)) 345 return false; 346 347 sync_api::WriteNode node(&trans); 348 std::string tag = AutofillModelAssociator::KeyToTag(entry.key().name(), 349 entry.key().value()); 350 if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag)) 351 return false; 352 353 AutofillChangeProcessor::WriteAutofillEntry(entry, &node); 354 return true; 355 } 356 357 bool AddAutofillSyncNode(const AutofillProfile& profile) { 358 sync_api::WriteTransaction trans(service_->GetUserShare()); 359 sync_api::ReadNode autofill_root(&trans); 360 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillProfileTag)) 361 return false; 362 sync_api::WriteNode node(&trans); 363 std::string tag = profile.guid(); 364 if (!node.InitUniqueByCreation(syncable::AUTOFILL_PROFILE, 365 autofill_root, tag)) 366 return false; 367 AutofillProfileChangeProcessor::WriteAutofillProfile(profile, &node); 368 return true; 369 } 370 371 bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries, 372 std::vector<AutofillProfile>* profiles) { 373 sync_api::ReadTransaction trans(service_->GetUserShare()); 374 sync_api::ReadNode autofill_root(&trans); 375 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag)) 376 return false; 377 378 int64 child_id = autofill_root.GetFirstChildId(); 379 while (child_id != sync_api::kInvalidId) { 380 sync_api::ReadNode child_node(&trans); 381 if (!child_node.InitByIdLookup(child_id)) 382 return false; 383 384 const sync_pb::AutofillSpecifics& autofill( 385 child_node.GetAutofillSpecifics()); 386 if (autofill.has_value()) { 387 AutofillKey key(UTF8ToUTF16(autofill.name()), 388 UTF8ToUTF16(autofill.value())); 389 std::vector<base::Time> timestamps; 390 int timestamps_count = autofill.usage_timestamp_size(); 391 for (int i = 0; i < timestamps_count; ++i) { 392 timestamps.push_back(Time::FromInternalValue( 393 autofill.usage_timestamp(i))); 394 } 395 entries->push_back(AutofillEntry(key, timestamps)); 396 } else if (autofill.has_profile()) { 397 AutofillProfile p; 398 p.set_guid(autofill.profile().guid()); 399 AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p, 400 autofill.profile()); 401 profiles->push_back(p); 402 } 403 child_id = child_node.GetSuccessorId(); 404 } 405 return true; 406 } 407 408 bool GetAutofillProfilesFromSyncDBUnderProfileNode( 409 std::vector<AutofillProfile>* profiles) { 410 sync_api::ReadTransaction trans(service_->GetUserShare()); 411 sync_api::ReadNode autofill_root(&trans); 412 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillProfileTag)) 413 return false; 414 415 int64 child_id = autofill_root.GetFirstChildId(); 416 while (child_id != sync_api::kInvalidId) { 417 sync_api::ReadNode child_node(&trans); 418 if (!child_node.InitByIdLookup(child_id)) 419 return false; 420 421 const sync_pb::AutofillProfileSpecifics& autofill( 422 child_node.GetAutofillProfileSpecifics()); 423 AutofillProfile p; 424 p.set_guid(autofill.guid()); 425 AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p, 426 autofill); 427 profiles->push_back(p); 428 child_id = child_node.GetSuccessorId(); 429 } 430 return true; 431 } 432 433 void SetIdleChangeProcessorExpectations() { 434 EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0); 435 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)).Times(0); 436 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).Times(0); 437 } 438 439 static AutofillEntry MakeAutofillEntry(const char* name, 440 const char* value, 441 time_t timestamp0, 442 time_t timestamp1) { 443 std::vector<Time> timestamps; 444 if (timestamp0 > 0) 445 timestamps.push_back(Time::FromTimeT(timestamp0)); 446 if (timestamp1 > 0) 447 timestamps.push_back(Time::FromTimeT(timestamp1)); 448 return AutofillEntry( 449 AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), timestamps); 450 } 451 452 static AutofillEntry MakeAutofillEntry(const char* name, 453 const char* value, 454 time_t timestamp) { 455 return MakeAutofillEntry(name, value, timestamp, -1); 456 } 457 458 friend class AddAutofillTask<AutofillEntry>; 459 friend class AddAutofillTask<AutofillProfile>; 460 friend class FakeServerUpdater; 461 462 BrowserThread db_thread_; 463 scoped_refptr<ThreadNotificationService> notification_service_; 464 465 ProfileMock profile_; 466 AutofillTableMock autofill_table_; 467 scoped_ptr<WebDatabaseFake> web_database_; 468 scoped_refptr<WebDataService> web_data_service_; 469 scoped_refptr<PersonalDataManagerMock> personal_data_manager_; 470 }; 471 472 template <class T> 473 class AddAutofillTask : public Task { 474 public: 475 AddAutofillTask(ProfileSyncServiceAutofillTest* test, 476 const std::vector<T>& entries) 477 : test_(test), entries_(entries), success_(false) { 478 } 479 480 virtual void Run() { 481 if (!test_->CreateRoot(GetModelType<T>())) 482 return; 483 for (size_t i = 0; i < entries_.size(); ++i) { 484 if (!test_->AddAutofillSyncNode(entries_[i])) 485 return; 486 } 487 success_ = true; 488 } 489 bool success() { return success_; } 490 491 private: 492 ProfileSyncServiceAutofillTest* test_; 493 const std::vector<T>& entries_; 494 bool success_; 495 }; 496 497 // Overload write transaction to use custom NotifyTransactionComplete 498 static const bool kLoggingInfo = true; 499 class WriteTransactionTest: public WriteTransaction { 500 public: 501 WriteTransactionTest(const syncable::ScopedDirLookup& directory, 502 WriterTag writer, const char* source_file, 503 int line, 504 scoped_ptr<WaitableEvent> *wait_for_syncapi) 505 : WriteTransaction(directory, writer, source_file, line), 506 wait_for_syncapi_(wait_for_syncapi) { } 507 508 virtual void NotifyTransactionComplete(syncable::ModelTypeBitSet types) { 509 // This is where we differ. Force a thread change here, giving another 510 // thread a chance to create a WriteTransaction 511 (*wait_for_syncapi_)->Wait(); 512 513 WriteTransaction::NotifyTransactionComplete(types); 514 } 515 516 private: 517 scoped_ptr<WaitableEvent> *wait_for_syncapi_; 518 }; 519 520 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can 521 // post tasks with it. 522 class FakeServerUpdater: public base::RefCountedThreadSafe<FakeServerUpdater> { 523 public: 524 FakeServerUpdater(TestProfileSyncService *service, 525 scoped_ptr<WaitableEvent> *wait_for_start, 526 scoped_ptr<WaitableEvent> *wait_for_syncapi) 527 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)), 528 service_(service), 529 wait_for_start_(wait_for_start), 530 wait_for_syncapi_(wait_for_syncapi), 531 is_finished_(false, false) { } 532 533 void Update() { 534 // This gets called in a modelsafeworker thread. 535 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 536 537 sync_api::UserShare* user_share = service_->GetUserShare(); 538 syncable::DirectoryManager* dir_manager = user_share->dir_manager.get(); 539 syncable::ScopedDirLookup dir(dir_manager, user_share->name); 540 ASSERT_TRUE(dir.good()); 541 542 // Create autofill protobuf 543 std::string tag = AutofillModelAssociator::KeyToTag(entry_.key().name(), 544 entry_.key().value()); 545 sync_pb::AutofillSpecifics new_autofill; 546 new_autofill.set_name(UTF16ToUTF8(entry_.key().name())); 547 new_autofill.set_value(UTF16ToUTF8(entry_.key().value())); 548 const std::vector<base::Time>& ts(entry_.timestamps()); 549 for (std::vector<base::Time>::const_iterator timestamp = ts.begin(); 550 timestamp != ts.end(); ++timestamp) { 551 new_autofill.add_usage_timestamp(timestamp->ToInternalValue()); 552 } 553 554 sync_pb::EntitySpecifics entity_specifics; 555 entity_specifics.MutableExtension(sync_pb::autofill)-> 556 CopyFrom(new_autofill); 557 558 { 559 // Tell main thread we've started 560 (*wait_for_start_)->Signal(); 561 562 // Create write transaction. 563 WriteTransactionTest trans(dir, UNITTEST, __FILE__, __LINE__, 564 wait_for_syncapi_); 565 566 // Create actual entry based on autofill protobuf information. 567 // Simulates effects of SyncerUtil::UpdateLocalDataFromServerData 568 MutableEntry parent(&trans, GET_BY_SERVER_TAG, kAutofillTag); 569 MutableEntry item(&trans, CREATE, parent.Get(syncable::ID), tag); 570 ASSERT_TRUE(item.good()); 571 item.Put(SPECIFICS, entity_specifics); 572 item.Put(SERVER_SPECIFICS, entity_specifics); 573 item.Put(BASE_VERSION, 1); 574 syncable::Id server_item_id = service_->id_factory()->NewServerId(); 575 item.Put(syncable::ID, server_item_id); 576 syncable::Id new_predecessor; 577 ASSERT_TRUE(item.PutPredecessor(new_predecessor)); 578 } 579 VLOG(1) << "FakeServerUpdater finishing."; 580 is_finished_.Signal(); 581 } 582 583 void CreateNewEntry(const AutofillEntry& entry) { 584 entry_ = entry; 585 scoped_ptr<Callback0::Type> c(NewCallback((FakeServerUpdater *)this, 586 &FakeServerUpdater::Update)); 587 std::vector<browser_sync::ModelSafeWorker*> workers; 588 service_->GetBackendForTest()->GetWorkers(&workers); 589 590 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 591 if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 592 NewRunnableMethod(this, &FakeServerUpdater::Update))) { 593 NOTREACHED() << "Failed to post task to the db thread."; 594 return; 595 } 596 } 597 598 void CreateNewEntryAndWait(const AutofillEntry& entry) { 599 entry_ = entry; 600 scoped_ptr<Callback0::Type> c(NewCallback((FakeServerUpdater *)this, 601 &FakeServerUpdater::Update)); 602 std::vector<browser_sync::ModelSafeWorker*> workers; 603 service_->GetBackendForTest()->GetWorkers(&workers); 604 605 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 606 is_finished_.Reset(); 607 if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 608 NewRunnableMethod(this, &FakeServerUpdater::Update))) { 609 NOTREACHED() << "Failed to post task to the db thread."; 610 return; 611 } 612 is_finished_.Wait(); 613 } 614 615 private: 616 friend class base::RefCountedThreadSafe<FakeServerUpdater>; 617 ~FakeServerUpdater() { } 618 619 AutofillEntry entry_; 620 TestProfileSyncService *service_; 621 scoped_ptr<WaitableEvent> *wait_for_start_; 622 scoped_ptr<WaitableEvent> *wait_for_syncapi_; 623 WaitableEvent is_finished_; 624 syncable::Id parent_id_; 625 }; 626 627 // TODO(skrul): Test abort startup. 628 // TODO(skrul): Test processing of cloud changes. 629 // TODO(tim): Add autofill data type controller test, and a case to cover 630 // waiting for the PersonalDataManager. 631 TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) { 632 // Don't create the root autofill node so startup fails. 633 StartSyncService(NULL, true, syncable::AUTOFILL); 634 EXPECT_TRUE(service_->unrecoverable_error_detected()); 635 } 636 637 TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) { 638 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true)); 639 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 640 SetIdleChangeProcessorExpectations(); 641 CreateRootTask task(this, syncable::AUTOFILL); 642 EXPECT_CALL(*personal_data_manager_, Refresh()); 643 StartSyncService(&task, false, syncable::AUTOFILL); 644 ASSERT_TRUE(task.success()); 645 std::vector<AutofillEntry> sync_entries; 646 std::vector<AutofillProfile> sync_profiles; 647 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 648 EXPECT_EQ(0U, sync_entries.size()); 649 EXPECT_EQ(0U, sync_profiles.size()); 650 } 651 652 TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) { 653 std::vector<AutofillEntry> entries; 654 entries.push_back(MakeAutofillEntry("foo", "bar", 1)); 655 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 656 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true))); 657 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 658 SetIdleChangeProcessorExpectations(); 659 CreateRootTask task(this, syncable::AUTOFILL); 660 EXPECT_CALL(*personal_data_manager_, Refresh()); 661 StartSyncService(&task, false, syncable::AUTOFILL); 662 ASSERT_TRUE(task.success()); 663 std::vector<AutofillEntry> sync_entries; 664 std::vector<AutofillProfile> sync_profiles; 665 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 666 ASSERT_EQ(1U, entries.size()); 667 EXPECT_TRUE(entries[0] == sync_entries[0]); 668 EXPECT_EQ(0U, sync_profiles.size()); 669 } 670 671 TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) { 672 673 std::vector<AutofillProfile*> profiles; 674 std::vector<AutofillProfile> expected_profiles; 675 // Owned by GetAutofillProfiles caller. 676 AutofillProfile* profile0 = new AutofillProfile; 677 autofill_test::SetProfileInfoWithGuid(profile0, 678 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing", 679 "Mitchell", "Morrison", 680 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 681 "91601", "US", "12345678910", "01987654321"); 682 profiles.push_back(profile0); 683 expected_profiles.push_back(*profile0); 684 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 685 WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true))); 686 EXPECT_CALL(*personal_data_manager_, Refresh()); 687 SetIdleChangeProcessorExpectations(); 688 CreateRootTask task(this, syncable::AUTOFILL_PROFILE); 689 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE); 690 ASSERT_TRUE(task.success()); 691 std::vector<AutofillProfile> sync_profiles; 692 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles)); 693 EXPECT_EQ(1U, sync_profiles.size()); 694 EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0])); 695 } 696 697 TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) { 698 // There is buggy autofill code that allows duplicate name/value 699 // pairs to exist in the database with separate pair_ids. 700 std::vector<AutofillEntry> entries; 701 entries.push_back(MakeAutofillEntry("foo", "bar", 1)); 702 entries.push_back(MakeAutofillEntry("dup", "", 2)); 703 entries.push_back(MakeAutofillEntry("dup", "", 3)); 704 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 705 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true))); 706 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 707 SetIdleChangeProcessorExpectations(); 708 CreateRootTask task(this, syncable::AUTOFILL); 709 EXPECT_CALL(*personal_data_manager_, Refresh()); 710 StartSyncService(&task, false, syncable::AUTOFILL); 711 ASSERT_TRUE(task.success()); 712 std::vector<AutofillEntry> sync_entries; 713 std::vector<AutofillProfile> sync_profiles; 714 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 715 EXPECT_EQ(2U, sync_entries.size()); 716 } 717 718 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) { 719 AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1)); 720 AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2)); 721 722 std::vector<AutofillEntry> native_entries; 723 native_entries.push_back(native_entry); 724 725 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 726 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true))); 727 728 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 729 730 std::vector<AutofillEntry> sync_entries; 731 sync_entries.push_back(sync_entry); 732 733 AddAutofillTask<AutofillEntry> task(this, sync_entries); 734 735 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(ElementsAre(sync_entry))). 736 WillOnce(Return(true)); 737 738 EXPECT_CALL(*personal_data_manager_, Refresh()); 739 StartSyncService(&task, false, syncable::AUTOFILL); 740 ASSERT_TRUE(task.success()); 741 742 std::set<AutofillEntry> expected_entries; 743 expected_entries.insert(native_entry); 744 expected_entries.insert(sync_entry); 745 746 std::vector<AutofillEntry> new_sync_entries; 747 std::vector<AutofillProfile> new_sync_profiles; 748 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 749 &new_sync_profiles)); 750 std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(), 751 new_sync_entries.end()); 752 753 EXPECT_TRUE(expected_entries == new_sync_entries_set); 754 } 755 756 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) { 757 AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1)); 758 AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2)); 759 AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2)); 760 761 std::vector<AutofillEntry> native_entries; 762 native_entries.push_back(native_entry); 763 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 764 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true))); 765 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 766 767 std::vector<AutofillEntry> sync_entries; 768 sync_entries.push_back(sync_entry); 769 AddAutofillTask<AutofillEntry> task(this, sync_entries); 770 771 EXPECT_CALL(autofill_table_, 772 UpdateAutofillEntries(ElementsAre(merged_entry))).WillOnce(Return(true)); 773 EXPECT_CALL(*personal_data_manager_, Refresh()); 774 StartSyncService(&task, false, syncable::AUTOFILL); 775 ASSERT_TRUE(task.success()); 776 777 std::vector<AutofillEntry> new_sync_entries; 778 std::vector<AutofillProfile> new_sync_profiles; 779 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 780 &new_sync_profiles)); 781 ASSERT_EQ(1U, new_sync_entries.size()); 782 EXPECT_TRUE(merged_entry == new_sync_entries[0]); 783 } 784 785 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) { 786 AutofillProfile sync_profile; 787 autofill_test::SetProfileInfoWithGuid(&sync_profile, 788 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", 789 "Mitchell", "Morrison", 790 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 791 "91601", "US", "12345678910", "01987654321"); 792 793 AutofillProfile* native_profile = new AutofillProfile; 794 autofill_test::SetProfileInfoWithGuid(native_profile, 795 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz", 796 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 797 "32801", "US", "19482937549", "13502849239"); 798 799 std::vector<AutofillProfile*> native_profiles; 800 native_profiles.push_back(native_profile); 801 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 802 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); 803 804 std::vector<AutofillProfile> sync_profiles; 805 sync_profiles.push_back(sync_profile); 806 AddAutofillTask<AutofillProfile> task(this, sync_profiles); 807 808 EXPECT_CALL(autofill_table_, UpdateAutofillProfile(_)). 809 WillOnce(Return(true)); 810 EXPECT_CALL(*personal_data_manager_, Refresh()); 811 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE); 812 ASSERT_TRUE(task.success()); 813 814 std::vector<AutofillProfile> new_sync_profiles; 815 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 816 &new_sync_profiles)); 817 ASSERT_EQ(1U, new_sync_profiles.size()); 818 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0])); 819 } 820 821 TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) { 822 AutofillProfile sync_profile; 823 824 autofill_test::SetProfileInfoWithGuid(&sync_profile, 825 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", 826 "Mitchell", "Morrison", 827 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 828 "91601", "US", "12345678910", "01987654321"); 829 830 std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B"; 831 AutofillProfile* native_profile = new AutofillProfile; 832 autofill_test::SetProfileInfoWithGuid(native_profile, 833 native_guid.c_str(), "Billing", 834 "Mitchell", "Morrison", 835 "johnwayne (at) me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", 836 "91601", "US", "12345678910", "01987654321"); 837 838 std::vector<AutofillProfile*> native_profiles; 839 native_profiles.push_back(native_profile); 840 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 841 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); 842 843 std::vector<AutofillProfile> sync_profiles; 844 sync_profiles.push_back(sync_profile); 845 AddAutofillTask<AutofillProfile> task(this, sync_profiles); 846 847 EXPECT_CALL(autofill_table_, AddAutofillProfile(_)). 848 WillOnce(Return(true)); 849 EXPECT_CALL(autofill_table_, RemoveAutofillProfile(native_guid)). 850 WillOnce(Return(true)); 851 EXPECT_CALL(*personal_data_manager_, Refresh()); 852 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE); 853 ASSERT_TRUE(task.success()); 854 855 std::vector<AutofillProfile> new_sync_profiles; 856 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 857 &new_sync_profiles)); 858 ASSERT_EQ(1U, new_sync_profiles.size()); 859 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0])); 860 EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid()); 861 } 862 863 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) { 864 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true)); 865 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 866 EXPECT_CALL(*personal_data_manager_, Refresh()); 867 SetIdleChangeProcessorExpectations(); 868 CreateRootTask task(this, syncable::AUTOFILL); 869 StartSyncService(&task, false, syncable::AUTOFILL); 870 ASSERT_TRUE(task.success()); 871 872 AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1)); 873 std::vector<base::Time> timestamps(added_entry.timestamps()); 874 875 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)). 876 WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true))); 877 878 AutofillChangeList changes; 879 changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key())); 880 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_)); 881 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, 882 Source<WebDataService>(web_data_service_.get()), 883 Details<AutofillChangeList>(&changes)); 884 885 std::vector<AutofillEntry> new_sync_entries; 886 std::vector<AutofillProfile> new_sync_profiles; 887 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 888 &new_sync_profiles)); 889 ASSERT_EQ(1U, new_sync_entries.size()); 890 EXPECT_TRUE(added_entry == new_sync_entries[0]); 891 } 892 893 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) { 894 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 895 EXPECT_CALL(*personal_data_manager_, Refresh()); 896 SetIdleChangeProcessorExpectations(); 897 CreateRootTask task(this, syncable::AUTOFILL_PROFILE); 898 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE); 899 ASSERT_TRUE(task.success()); 900 901 AutofillProfile added_profile; 902 autofill_test::SetProfileInfoWithGuid(&added_profile, 903 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz", 904 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 905 "32801", "US", "19482937549", "13502849239"); 906 907 AutofillProfileChange change(AutofillProfileChange::ADD, 908 added_profile.guid(), &added_profile); 909 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_)); 910 notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, 911 Source<WebDataService>(web_data_service_.get()), 912 Details<AutofillProfileChange>(&change)); 913 914 std::vector<AutofillProfile> new_sync_profiles; 915 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 916 &new_sync_profiles)); 917 ASSERT_EQ(1U, new_sync_profiles.size()); 918 EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0])); 919 } 920 921 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) { 922 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); 923 std::vector<AutofillEntry> original_entries; 924 original_entries.push_back(original_entry); 925 926 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 927 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true))); 928 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 929 EXPECT_CALL(*personal_data_manager_, Refresh()); 930 CreateRootTask task(this, syncable::AUTOFILL); 931 StartSyncService(&task, false, syncable::AUTOFILL); 932 ASSERT_TRUE(task.success()); 933 934 AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2)); 935 std::vector<base::Time> timestamps(updated_entry.timestamps()); 936 937 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)). 938 WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true))); 939 940 AutofillChangeList changes; 941 changes.push_back(AutofillChange(AutofillChange::UPDATE, 942 updated_entry.key())); 943 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_)); 944 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, 945 Source<WebDataService>(web_data_service_.get()), 946 Details<AutofillChangeList>(&changes)); 947 948 std::vector<AutofillEntry> new_sync_entries; 949 std::vector<AutofillProfile> new_sync_profiles; 950 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 951 &new_sync_profiles)); 952 ASSERT_EQ(1U, new_sync_entries.size()); 953 EXPECT_TRUE(updated_entry == new_sync_entries[0]); 954 } 955 956 957 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) { 958 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); 959 std::vector<AutofillEntry> original_entries; 960 original_entries.push_back(original_entry); 961 962 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)). 963 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true))); 964 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 965 EXPECT_CALL(*personal_data_manager_, Refresh()); 966 CreateRootTask task(this, syncable::AUTOFILL); 967 StartSyncService(&task, false, syncable::AUTOFILL); 968 ASSERT_TRUE(task.success()); 969 970 AutofillChangeList changes; 971 changes.push_back(AutofillChange(AutofillChange::REMOVE, 972 original_entry.key())); 973 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_)); 974 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, 975 Source<WebDataService>(web_data_service_.get()), 976 Details<AutofillChangeList>(&changes)); 977 978 std::vector<AutofillEntry> new_sync_entries; 979 std::vector<AutofillProfile> new_sync_profiles; 980 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, 981 &new_sync_profiles)); 982 ASSERT_EQ(0U, new_sync_entries.size()); 983 } 984 985 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { 986 AutofillProfile sync_profile; 987 autofill_test::SetProfileInfoWithGuid(&sync_profile, 988 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz", 989 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 990 "32801", "US", "19482937549", "13502849239"); 991 AutofillProfile* native_profile = new AutofillProfile; 992 autofill_test::SetProfileInfoWithGuid(native_profile, 993 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz", 994 "joewayne (at) me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", 995 "32801", "US", "19482937549", "13502849239"); 996 997 std::vector<AutofillProfile*> native_profiles; 998 native_profiles.push_back(native_profile); 999 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)). 1000 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); 1001 1002 std::vector<AutofillProfile> sync_profiles; 1003 sync_profiles.push_back(sync_profile); 1004 AddAutofillTask<AutofillProfile> task(this, sync_profiles); 1005 EXPECT_CALL(*personal_data_manager_, Refresh()); 1006 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE); 1007 ASSERT_TRUE(task.success()); 1008 1009 AutofillProfileChange change(AutofillProfileChange::REMOVE, 1010 sync_profile.guid(), NULL); 1011 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_)); 1012 notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, 1013 Source<WebDataService>(web_data_service_.get()), 1014 Details<AutofillProfileChange>(&change)); 1015 1016 std::vector<AutofillProfile> new_sync_profiles; 1017 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( 1018 &new_sync_profiles)); 1019 ASSERT_EQ(0U, new_sync_profiles.size()); 1020 } 1021 1022 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeError) { 1023 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true)); 1024 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 1025 EXPECT_CALL(*personal_data_manager_, Refresh()); 1026 CreateRootTask task(this, syncable::AUTOFILL); 1027 StartSyncService(&task, false, syncable::AUTOFILL); 1028 ASSERT_TRUE(task.success()); 1029 1030 // Inject an evil entry into the sync db to conflict with the same 1031 // entry added by the user. 1032 AutofillEntry evil_entry(MakeAutofillEntry("evil", "entry", 1)); 1033 ASSERT_TRUE(AddAutofillSyncNode(evil_entry)); 1034 1035 AutofillChangeList changes; 1036 changes.push_back(AutofillChange(AutofillChange::ADD, 1037 evil_entry.key())); 1038 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_)); 1039 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, 1040 Source<WebDataService>(web_data_service_.get()), 1041 Details<AutofillChangeList>(&changes)); 1042 1043 // Wait for the PPS to shut everything down and signal us. 1044 ProfileSyncServiceObserverMock observer; 1045 service_->AddObserver(&observer); 1046 EXPECT_CALL(observer, OnStateChanged()).WillOnce(QuitUIMessageLoop()); 1047 MessageLoop::current()->Run(); 1048 EXPECT_TRUE(service_->unrecoverable_error_detected()); 1049 1050 // Ensure future autofill notifications don't crash. 1051 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, 1052 Source<WebDataService>(web_data_service_.get()), 1053 Details<AutofillChangeList>(&changes)); 1054 } 1055 1056 // Crashy, http://crbug.com/57884 1057 TEST_F(ProfileSyncServiceAutofillTest, DISABLED_ServerChangeRace) { 1058 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true)); 1059 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true)); 1060 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)). 1061 WillRepeatedly(Return(true)); 1062 EXPECT_CALL(*personal_data_manager_, Refresh()).Times(3); 1063 CreateRootTask task(this, syncable::AUTOFILL); 1064 StartSyncService(&task, false, syncable::AUTOFILL); 1065 ASSERT_TRUE(task.success()); 1066 1067 // (true, false) means we have to reset after |Signal|, init to unsignaled. 1068 scoped_ptr<WaitableEvent> wait_for_start(new WaitableEvent(true, false)); 1069 scoped_ptr<WaitableEvent> wait_for_syncapi(new WaitableEvent(true, false)); 1070 scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater( 1071 service_.get(), &wait_for_start, &wait_for_syncapi)); 1072 1073 // This server side update will stall waiting for CommitWaiter. 1074 updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1)); 1075 wait_for_start->Wait(); 1076 1077 AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2)); 1078 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry)); 1079 VLOG(1) << "Syncapi update finished."; 1080 1081 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay! 1082 // Signal FakeServerUpdater that it can complete. 1083 wait_for_syncapi->Signal(); 1084 1085 // Make another entry to ensure nothing broke afterwards and wait for finish 1086 // to clean up. 1087 updater->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3)); 1088 1089 std::vector<AutofillEntry> sync_entries; 1090 std::vector<AutofillProfile> sync_profiles; 1091 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); 1092 EXPECT_EQ(3U, sync_entries.size()); 1093 EXPECT_EQ(0U, sync_profiles.size()); 1094 for (size_t i = 0; i < sync_entries.size(); i++) { 1095 VLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name() 1096 << ", " << sync_entries[i].key().value(); 1097 } 1098 } 1099