15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/passwords_helper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_factory.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h" 15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/sync_datatype_helper.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/password_form_data.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/password_store.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/password_store_consumer.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using autofill::PasswordForm; 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochusing password_manager::PasswordStore; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_datatype_helper::test; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string kFakeSignonRealm = "http://fake-signon-realm.google.com/"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kIndexedFakeOrigin = "http://fake-signon-realm.google.com/%d"; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use a WaitableEvent to wait when logins are added, removed, or updated 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead of running the UI message loop because of a restriction that 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prevents a DB thread from initiating a quit of the UI message loop. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreCallback(base::WaitableEvent* wait_event) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wake up passwords_helper::AddLogin. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event->Signal(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass PasswordStoreConsumerHelper 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : public password_manager::PasswordStoreConsumer { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit PasswordStoreConsumerHelper(std::vector<PasswordForm>* result) 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : password_manager::PasswordStoreConsumer(), result_(result) {} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnGetPasswordStoreResults( 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<PasswordForm*>& result) OVERRIDE { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_->clear(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PasswordForm*>::const_iterator it = result.begin(); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != result.end(); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_->push_back(**it); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete *it; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Quit the message loop to wake up passwords_helper::GetLogins. 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForUI::current()->Quit(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm>* result_; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PasswordStoreConsumerHelper); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// PasswordForm::date_synced is a local field. Therefore it may be different 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// across clients. 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ClearSyncDateField(std::vector<PasswordForm>* forms) { 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (std::vector<PasswordForm>::iterator it = forms->begin(); 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it != forms->end(); 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ++it) { 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it->date_synced = base::Time(); 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace passwords_helper { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddLogin(PasswordStore* store, const PasswordForm& form) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(store); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent wait_event(true, false); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->AddLogin(form); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event.Wait(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateLogin(PasswordStore* store, const PasswordForm& form) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(store); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent wait_event(true, false); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->UpdateLogin(form); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event)); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event.Wait(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetLogins(PasswordStore* store, std::vector<PasswordForm>& matches) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(store); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordForm matcher_form; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matcher_form.signon_realm = kFakeSignonRealm; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreConsumerHelper consumer(&matches); 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) store->GetLogins(matcher_form, PasswordStore::DISALLOW_PROMPT, &consumer); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunMessageLoop(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveLogin(PasswordStore* store, const PasswordForm& form) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(store); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent wait_event(true, false); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->RemoveLogin(form); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event)); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event.Wait(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveLogins(PasswordStore* store) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> forms; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLogins(store, forms); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PasswordForm>::iterator it = forms.begin(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != forms.end(); ++it) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveLogin(store, *it); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetEncryptionPassphrase(int index, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& passphrase, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService::PassphraseType type) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncServiceFactory::GetForProfile( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test()->GetProfile(index))->SetEncryptionPassphrase(passphrase, type); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetDecryptionPassphrase(int index, const std::string& passphrase) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProfileSyncServiceFactory::GetForProfile( 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test()->GetProfile(index))->SetDecryptionPassphrase(passphrase); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStore* GetPasswordStore(int index) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PasswordStoreFactory::GetForProfile(test()->GetProfile(index), 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Profile::IMPLICIT_ACCESS).get(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStore* GetVerifierPasswordStore() { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PasswordStoreFactory::GetForProfile(test()->verifier(), 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Profile::IMPLICIT_ACCESS).get(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileContainsSamePasswordFormsAsVerifier(int index) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> verifier_forms; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> forms; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLogins(GetVerifierPasswordStore(), verifier_forms); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLogins(GetPasswordStore(index), forms); 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ClearSyncDateField(&forms); 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool result = 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch password_manager::ContainsSamePasswordForms(verifier_forms, forms); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Password forms in Verifier Profile:"; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PasswordForm>::iterator it = verifier_forms.begin(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != verifier_forms.end(); ++it) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << *it << std::endl; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Password forms in Profile" << index << ":"; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PasswordForm>::iterator it = forms.begin(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != forms.end(); ++it) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << *it << std::endl; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfilesContainSamePasswordForms(int index_a, int index_b) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> forms_a; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> forms_b; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLogins(GetPasswordStore(index_a), forms_a); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLogins(GetPasswordStore(index_b), forms_b); 173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ClearSyncDateField(&forms_a); 174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ClearSyncDateField(&forms_b); 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool result = password_manager::ContainsSamePasswordForms(forms_a, forms_b); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Password forms in Profile" << index_a << ":"; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PasswordForm>::iterator it = forms_a.begin(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != forms_a.end(); ++it) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << *it << std::endl; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Password forms in Profile" << index_b << ":"; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PasswordForm>::iterator it = forms_b.begin(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != forms_b.end(); ++it) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << *it << std::endl; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AllProfilesContainSamePasswordFormsAsVerifier() { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < test()->num_clients(); ++i) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ProfileContainsSamePasswordFormsAsVerifier(i)) { 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DVLOG(1) << "Profile " << i << " does not contain the same password" 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " forms as the verifier."; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AllProfilesContainSamePasswordForms() { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 1; i < test()->num_clients(); ++i) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ProfilesContainSamePasswordForms(0, i)) { 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DVLOG(1) << "Profile " << i << " does not contain the same password" 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " forms as Profile 0."; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace { 214a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Helper class used in the implementation of 216a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// AwaitAllProfilesContainSamePasswordForms. 217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass SamePasswordFormsChecker : public MultiClientStatusChangeChecker { 218a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public: 219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SamePasswordFormsChecker(); 220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual ~SamePasswordFormsChecker(); 221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual bool IsExitConditionSatisfied() OVERRIDE; 223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual std::string GetDebugMessage() const OVERRIDE; 2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 2265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool in_progress_; 2275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool needs_recheck_; 228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 230a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSamePasswordFormsChecker::SamePasswordFormsChecker() 231a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : MultiClientStatusChangeChecker( 2325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu sync_datatype_helper::test()->GetSyncServices()), 2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu in_progress_(false), 2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu needs_recheck_(false) {} 235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 236a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSamePasswordFormsChecker::~SamePasswordFormsChecker() {} 237a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This method needs protection against re-entrancy. 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 2405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This function indirectly calls GetLogins(), which starts a RunLoop on the UI 2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// thread. This can be a problem, since the next task to execute could very 2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// well contain a ProfileSyncService::OnStateChanged() event, which would 2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// trigger another call to this here function, and start another layer of 2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// nested RunLoops. That makes the StatusChangeChecker's Quit() method 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// ineffective. 2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// The work-around is to not allow re-entrancy. But we can't just drop 2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// IsExitConditionSatisifed() calls if one is already in progress. Instead, we 2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// set a flag to ask the current execution of IsExitConditionSatisfied() to be 2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// re-run. This ensures that the return value is always based on the most 2515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// up-to-date state. 252a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool SamePasswordFormsChecker::IsExitConditionSatisfied() { 2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (in_progress_) { 2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LOG(WARNING) << "Setting flag and returning early to prevent nesting."; 2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu needs_recheck_ = true; 2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Keep retrying until we get a good reading. 2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool result = false; 2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu in_progress_ = true; 2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu do { 2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu needs_recheck_ = false; 2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result = AllProfilesContainSamePasswordForms(); 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } while (needs_recheck_); 2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu in_progress_ = false; 2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return result; 268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochstd::string SamePasswordFormsChecker::GetDebugMessage() const { 271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return "Waiting for matching passwords"; 272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace 275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool AwaitAllProfilesContainSamePasswordForms() { 277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SamePasswordFormsChecker checker; 278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch checker.Wait(); 279a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return !checker.TimedOut(); 280a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace { 283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Helper class used in the implementation of 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// AwaitProfileContainSamePasswordFormsAsVerifier. 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class SamePasswordFormsAsVerifierChecker 287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : public SingleClientStatusChangeChecker { 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public: 289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) explicit SamePasswordFormsAsVerifierChecker(int index); 290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual ~SamePasswordFormsAsVerifierChecker(); 291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual bool IsExitConditionSatisfied() OVERRIDE; 293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual std::string GetDebugMessage() const OVERRIDE; 294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 295010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private: 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int index_; 297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool in_progress_; 299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool needs_recheck_; 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)SamePasswordFormsAsVerifierChecker::SamePasswordFormsAsVerifierChecker(int i) 303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : SingleClientStatusChangeChecker( 304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) sync_datatype_helper::test()->GetSyncService(i)), 305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index_(i), 306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) in_progress_(false), 307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) needs_recheck_(false) { 308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)SamePasswordFormsAsVerifierChecker::~SamePasswordFormsAsVerifierChecker() { 311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This method uses the same re-entrancy prevention trick as 314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// the SamePasswordFormsChecker. 315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool SamePasswordFormsAsVerifierChecker::IsExitConditionSatisfied() { 316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (in_progress_) { 317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(WARNING) << "Setting flag and returning early to prevent nesting."; 318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) needs_recheck_ = true; 319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Keep retrying until we get a good reading. 323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool result = false; 324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) in_progress_ = true; 325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) do { 326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) needs_recheck_ = false; 327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result = ProfileContainsSamePasswordFormsAsVerifier(index_); 328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } while (needs_recheck_); 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) in_progress_ = false; 330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return result; 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)std::string SamePasswordFormsAsVerifierChecker::GetDebugMessage() const { 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return "Waiting for passwords to match verifier"; 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool AwaitProfileContainsSamePasswordFormsAsVerifier(int index) { 340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SamePasswordFormsAsVerifierChecker checker(index); 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) checker.Wait(); 342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return !checker.TimedOut(); 343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetPasswordCount(int index) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> forms; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLogins(GetPasswordStore(index), forms); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return forms.size(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetVerifierPasswordCount() { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> verifier_forms; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLogins(GetVerifierPasswordStore(), verifier_forms); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return verifier_forms.size(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordForm CreateTestPasswordForm(int index) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordForm form; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form.signon_realm = kFakeSignonRealm; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form.origin = GURL(base::StringPrintf(kIndexedFakeOrigin, index)); 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) form.username_value = 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ASCIIToUTF16(base::StringPrintf("username%d", index)); 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) form.password_value = 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ASCIIToUTF16(base::StringPrintf("password%d", index)); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form.date_created = base::Time::Now(); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return form; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace passwords_helper 370