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 <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