diff options
author | skrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-30 17:07:40 +0000 |
---|---|---|
committer | skrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-30 17:07:40 +0000 |
commit | de326e142065a56afd98b6c4e0e155c88d2690f3 (patch) | |
tree | 4fb7a52f26cd26708553cf7f78c11e3bf5f07c34 | |
parent | 7154e601b5a4d530ecc4ce0bfa13554b31d90444 (diff) | |
download | chromium_src-de326e142065a56afd98b6c4e0e155c88d2690f3.zip chromium_src-de326e142065a56afd98b6c4e0e155c88d2690f3.tar.gz chromium_src-de326e142065a56afd98b6c4e0e155c88d2690f3.tar.bz2 |
Adds TwoClientLiveAutofillSyncTest to test old school autofill. Includes some refactoring of the WebDataServiceTest to allow some code sharing between the two.
Review URL: http://codereview.chromium.org/1739017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46080 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/go_button_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/sync/glue/autofill_change_processor.cc | 8 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service_autofill_unittest.cc | 22 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_test_util.h | 21 | ||||
-rw-r--r-- | chrome/browser/webdata/autofill_entry.h | 6 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service.cc | 7 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service_test_util.h | 43 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service_unittest.cc | 81 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 4 | ||||
-rw-r--r-- | chrome/test/live_sync/profile_sync_service_test_harness.cc | 1 | ||||
-rw-r--r-- | chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc | 275 | ||||
-rw-r--r-- | chrome/test/thread_observer_helper.h | 70 |
12 files changed, 452 insertions, 88 deletions
diff --git a/chrome/browser/gtk/go_button_gtk.cc b/chrome/browser/gtk/go_button_gtk.cc index 2df9932..187ace0 100644 --- a/chrome/browser/gtk/go_button_gtk.cc +++ b/chrome/browser/gtk/go_button_gtk.cc @@ -59,7 +59,7 @@ GoButtonGtk::GoButtonGtk(LocationBarViewGtk* location_bar, Browser* browser) theme_provider_->InitThemesFor(this); registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources()); + Source<GtkThemeProvider>(theme_provider_)); } } diff --git a/chrome/browser/sync/glue/autofill_change_processor.cc b/chrome/browser/sync/glue/autofill_change_processor.cc index 7735e16..4db970d 100644 --- a/chrome/browser/sync/glue/autofill_change_processor.cc +++ b/chrome/browser/sync/glue/autofill_change_processor.cc @@ -45,11 +45,15 @@ void AutofillChangeProcessor::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { LOG(INFO) << "Observed autofill change."; + // Ensure this notification came from our web database. + WebDataService* wds = Source<WebDataService>(source).ptr(); + if (!wds || wds->GetDatabase() != web_database_) + return; + DCHECK(running()); DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); - if (!observing_) { + if (!observing_) return; - } sync_api::WriteTransaction trans(share_handle()); sync_api::ReadNode autofill_root(&trans); diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc index b64136e..4ab3e12 100644 --- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc @@ -29,6 +29,7 @@ #include "chrome/browser/webdata/autofill_change.h" #include "chrome/browser/webdata/autofill_entry.h" #include "chrome/browser/webdata/web_database.h" +#include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" #include "chrome/test/sync/engine/test_id_factory.h" #include "chrome/test/profile_mock.h" @@ -94,15 +95,17 @@ class WebDatabaseMock : public WebDatabase { class WebDataServiceFake : public WebDataService { public: + WebDataServiceFake(WebDatabase* web_database) : web_database_(web_database) {} virtual bool IsDatabaseLoaded() { return true; } - // Note that we inject the WebDatabase through the - // ProfileSyncFactory mock. virtual WebDatabase* GetDatabase() { - return NULL; + return web_database_; } + + private: + WebDatabase* web_database_; }; class PersonalDataManagerMock: public PersonalDataManager { @@ -131,7 +134,7 @@ class ProfileSyncServiceAutofillTest : public testing::Test { } virtual void SetUp() { - web_data_service_ = new WebDataServiceFake(); + web_data_service_ = new WebDataServiceFake(&web_database_); personal_data_manager_.Init(&profile_); db_thread_.Start(); @@ -660,6 +663,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) { changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key())); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillChangeList>(&changes)); std::vector<AutofillEntry> new_sync_entries; @@ -686,6 +690,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) { added_profile.Label(), &added_profile, string16()); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillProfileChange>(&change)); std::vector<AutofillEntry> new_sync_entries; @@ -732,6 +737,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfileConflict) { scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillProfileChange>(&change)); std::vector<AutofillEntry> new_sync_entries; @@ -767,6 +773,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) { updated_entry.key())); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillChangeList>(&changes)); std::vector<AutofillEntry> new_sync_entries; @@ -802,6 +809,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateProfile) { ASCIIToUTF16("Billing")); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillProfileChange>(&change)); std::vector<AutofillEntry> new_sync_entries; @@ -836,6 +844,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateProfileRelabel) { ASCIIToUTF16("Billing")); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillProfileChange>(&change)); std::vector<AutofillEntry> new_sync_entries; @@ -881,6 +890,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ASCIIToUTF16("Billing")); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillProfileChange>(&change)); std::vector<AutofillEntry> new_sync_entries; @@ -910,6 +920,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) { original_entry.key())); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillChangeList>(&changes)); std::vector<AutofillEntry> new_sync_entries; @@ -948,6 +959,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { sync_profile.Label(), NULL, string16()); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillProfileChange>(&change)); std::vector<AutofillEntry> new_sync_entries; @@ -972,6 +984,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeError) { evil_entry.key())); scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_); notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillChangeList>(&changes)); // Wait for the PPS to shut everything down and signal us. @@ -981,5 +994,6 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeError) { // Ensure future autofill notifications don't crash. notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED, + Source<WebDataService>(web_data_service_.get()), Details<AutofillChangeList>(&changes)); } diff --git a/chrome/browser/sync/profile_sync_test_util.h b/chrome/browser/sync/profile_sync_test_util.h index 1e8842a..eeedc2d 100644 --- a/chrome/browser/sync/profile_sync_test_util.h +++ b/chrome/browser/sync/profile_sync_test_util.h @@ -28,6 +28,7 @@ #include "chrome/browser/sync/unrecoverable_error_handler.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" #include "chrome/test/sync/test_http_bridge_factory.h" #include "testing/gmock/include/gmock/gmock.h" @@ -196,20 +197,30 @@ class ThreadNotifier : // NOLINT notify_thread_(notify_thread) {} void Notify(NotificationType type, const NotificationDetails& details) { + Notify(type, NotificationService::AllSources(), details); + } + + void Notify(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); notify_thread_->message_loop()->PostTask( FROM_HERE, - NewRunnableMethod(this, &ThreadNotifier::NotifyTask, type, details)); + NewRunnableMethod(this, + &ThreadNotifier::NotifyTask, + type, + source, + details)); done_event_.Wait(); } private: friend class base::RefCountedThreadSafe<ThreadNotifier>; - void NotifyTask(NotificationType type, const NotificationDetails& details) { - NotificationService::current()->Notify(type, - NotificationService::AllSources(), - details); + void NotifyTask(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + NotificationService::current()->Notify(type, source, details); done_event_.Signal(); } diff --git a/chrome/browser/webdata/autofill_entry.h b/chrome/browser/webdata/autofill_entry.h index d67a090..8781fbd 100644 --- a/chrome/browser/webdata/autofill_entry.h +++ b/chrome/browser/webdata/autofill_entry.h @@ -7,7 +7,9 @@ #include <vector> #include "base/string16.h" +#include "base/string_util.h" #include "base/time.h" +#include "base/utf_string_conversions.h" class AutofillKey { public: @@ -15,11 +17,13 @@ class AutofillKey { AutofillKey(const string16& name, const string16& value) : name_(name), value_(value) {} + AutofillKey(const char* name, const char* value) + : name_(UTF8ToUTF16(name)), + value_(UTF8ToUTF16(value)) {} AutofillKey(const AutofillKey& key) : name_(key.name()), value_(key.value()) {} virtual ~AutofillKey() {} - const string16& name() const { return name_; } const string16& value() const { return value_; } diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc index 1a66823..c6ef778 100644 --- a/chrome/browser/webdata/web_data_service.cc +++ b/chrome/browser/webdata/web_data_service.cc @@ -16,6 +16,7 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -794,7 +795,7 @@ void WebDataService::AddFormElementsImpl( // done on the DB thread, and not the UI thread. NotificationService::current()->Notify( NotificationType::AUTOFILL_ENTRIES_CHANGED, - NotificationService::AllSources(), + Source<WebDataService>(this), Details<AutofillChangeList>(&changes)); } @@ -830,7 +831,7 @@ void WebDataService::RemoveFormElementsAddedBetweenImpl( // will be done on the DB thread, and not the UI thread. NotificationService::current()->Notify( NotificationType::AUTOFILL_ENTRIES_CHANGED, - NotificationService::AllSources(), + Source<WebDataService>(this), Details<AutofillChangeList>(&changes)); } ScheduleCommit(); @@ -857,7 +858,7 @@ void WebDataService::RemoveFormValueForElementNameImpl( // Post the notifications including the list of affected keys. NotificationService::current()->Notify( NotificationType::AUTOFILL_ENTRIES_CHANGED, - NotificationService::AllSources(), + Source<WebDataService>(this), Details<AutofillChangeList>(&changes)); } } diff --git a/chrome/browser/webdata/web_data_service_test_util.h b/chrome/browser/webdata/web_data_service_test_util.h new file mode 100644 index 0000000..31abfac --- /dev/null +++ b/chrome/browser/webdata/web_data_service_test_util.h @@ -0,0 +1,43 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_TEST_UTIL_H__ +#define CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_TEST_UTIL_H__ + +#include <vector> + +#include "base/basictypes.h" +#include "base/message_loop.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/webdata/web_data_service.h" + +class AutofillWebDataServiceConsumer: public WebDataServiceConsumer { + public: + AutofillWebDataServiceConsumer() : handle_(0) {} + virtual ~AutofillWebDataServiceConsumer() {} + + virtual void OnWebDataServiceRequestDone(WebDataService::Handle handle, + const WDTypedResult* result) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(result->GetType() == AUTOFILL_VALUE_RESULT); + handle_ = handle; + const WDResult<std::vector<string16> >* autofill_result = + static_cast<const WDResult<std::vector<string16> >*>(result); + // Copy the values. + values_ = autofill_result->GetValue(); + + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + MessageLoop::current()->Quit(); + } + + WebDataService::Handle handle() { return handle_; } + const std::vector<string16>& values() { return values_; } + + private: + WebDataService::Handle handle_; + std::vector<string16> values_; + DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer); +}; + +#endif // CHROME_BROWSER_WEBDATA_WEB_DATA_SERVICE_TEST_UTIL_H__ diff --git a/chrome/browser/webdata/web_data_service_unittest.cc b/chrome/browser/webdata/web_data_service_unittest.cc index fa65ff8..3b31429 100644 --- a/chrome/browser/webdata/web_data_service_unittest.cc +++ b/chrome/browser/webdata/web_data_service_unittest.cc @@ -20,12 +20,12 @@ #include "chrome/browser/webdata/autofill_change.h" #include "chrome/browser/webdata/autofill_entry.h" #include "chrome/browser/webdata/web_data_service.h" +#include "chrome/browser/webdata/web_data_service_test_util.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/notification_details.h" -#include "chrome/common/notification_observer_mock.h" -#include "chrome/common/notification_registrar.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" +#include "chrome/test/thread_observer_helper.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" @@ -48,64 +48,9 @@ ACTION_P(SignalEvent, event) { event->Signal(); } -class AutofillWebDataServiceConsumer: public WebDataServiceConsumer { - public: - AutofillWebDataServiceConsumer() : handle_(0) {} - virtual ~AutofillWebDataServiceConsumer() {} - - virtual void OnWebDataServiceRequestDone(WebDataService::Handle handle, - const WDTypedResult* result) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - DCHECK(result->GetType() == AUTOFILL_VALUE_RESULT); - handle_ = handle; - const WDResult<std::vector<string16> >* autofill_result = - static_cast<const WDResult<std::vector<string16> >*>(result); - // Copy the values. - values_ = autofill_result->GetValue(); - - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - MessageLoop::current()->Quit(); - } - - WebDataService::Handle handle() { return handle_; } - const std::vector<string16>& values() { return values_; } - - private: - WebDataService::Handle handle_; - std::vector<string16> values_; - DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer); -}; - -// This class will add and remove a mock notification observer from -// the DB thread. -class DBThreadObserverHelper : - public base::RefCountedThreadSafe<DBThreadObserverHelper, - ChromeThread::DeleteOnDBThread> { - public: - DBThreadObserverHelper() : done_event_(true, false) {} - - void Init() { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - ChromeThread::PostTask( - ChromeThread::DB, - FROM_HERE, - NewRunnableMethod(this, &DBThreadObserverHelper::AddObserverTask)); - done_event_.Wait(); - } - - virtual ~DBThreadObserverHelper() { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); - registrar_.RemoveAll(); - } - - NotificationObserverMock* observer() { - return &observer_; - } - - private: - friend class base::RefCountedThreadSafe<DBThreadObserverHelper>; - - void AddObserverTask() { +class AutofillDBThreadObserverHelper : public DBThreadObserverHelper { + protected: + virtual void RegisterObservers() { registrar_.Add(&observer_, NotificationType::AUTOFILL_ENTRIES_CHANGED, NotificationService::AllSources()); @@ -115,12 +60,7 @@ class DBThreadObserverHelper : registrar_.Add(&observer_, NotificationType::AUTOFILL_CREDIT_CARD_CHANGED, NotificationService::AllSources()); - done_event_.Signal(); } - - WaitableEvent done_event_; - NotificationRegistrar registrar_; - NotificationObserverMock observer_; }; class WebDataServiceTest : public testing::Test { @@ -175,7 +115,7 @@ class WebDataServiceAutofillTest : public WebDataServiceTest { name2_ = ASCIIToUTF16("name2"); value1_ = ASCIIToUTF16("value1"); value2_ = ASCIIToUTF16("value2"); - observer_helper_ = new DBThreadObserverHelper(); + observer_helper_ = new AutofillDBThreadObserverHelper(); observer_helper_->Init(); } @@ -201,7 +141,7 @@ class WebDataServiceAutofillTest : public WebDataServiceTest { string16 value2_; int unique_id1_, unique_id2_; const TimeDelta test_timeout_; - scoped_refptr<DBThreadObserverHelper> observer_helper_; + scoped_refptr<AutofillDBThreadObserverHelper> observer_helper_; WaitableEvent done_event_; }; @@ -216,7 +156,7 @@ TEST_F(WebDataServiceAutofillTest, FormFillAdd) { EXPECT_CALL( *observer_helper_->observer(), Observe(NotificationType(NotificationType::AUTOFILL_ENTRIES_CHANGED), - NotificationService::AllSources(), + Source<WebDataService>(wds_.get()), Property(&Details<const AutofillChangeList>::ptr, Pointee(ElementsAreArray(expected_changes))))). WillOnce(SignalEvent(&done_event_)); @@ -262,7 +202,7 @@ TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) { EXPECT_CALL( *observer_helper_->observer(), Observe(NotificationType(NotificationType::AUTOFILL_ENTRIES_CHANGED), - NotificationService::AllSources(), + Source<WebDataService>(wds_.get()), Property(&Details<const AutofillChangeList>::ptr, Pointee(ElementsAreArray(expected_changes))))). WillOnce(SignalEvent(&done_event_)); @@ -295,7 +235,7 @@ TEST_F(WebDataServiceAutofillTest,FormFillRemoveMany) { EXPECT_CALL( *observer_helper_->observer(), Observe(NotificationType(NotificationType::AUTOFILL_ENTRIES_CHANGED), - NotificationService::AllSources(), + Source<WebDataService>(wds_.get()), Property(&Details<const AutofillChangeList>::ptr, Pointee(ElementsAreArray(expected_changes))))). WillOnce(SignalEvent(&done_event_)); @@ -442,4 +382,3 @@ TEST_F(WebDataServiceAutofillTest, CreditUpdate) { wds_->UpdateCreditCard(card1_delta); done_event_.TimedWait(test_timeout_); } - diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 85497a3..9633673 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -135,6 +135,7 @@ 'test/test_location_bar.h', 'test/testing_profile.cc', 'test/testing_profile.h', + 'test/thread_observer_helper.h', 'test/ui_test_utils.cc', 'test/ui_test_utils.h', 'test/ui_test_utils_linux.cc', @@ -952,6 +953,7 @@ 'browser/views/generic_info_view_unittest.cc', 'browser/views/status_icons/status_tray_win_unittest.cc', 'browser/visitedlink_unittest.cc', + 'browser/webdata/web_data_service_test_util.h', 'browser/webdata/web_data_service_unittest.cc', 'browser/webdata/web_database_unittest.cc', 'browser/window_sizer_unittest.cc', @@ -1823,6 +1825,7 @@ '../net/net.gyp:net_test_support', '../printing/printing.gyp:printing', '../skia/skia.gyp:skia', + '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', '../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icuuc', @@ -1852,6 +1855,7 @@ 'test/live_sync/profile_sync_service_test_harness.h', 'test/live_sync/single_client_live_bookmarks_sync_unittest.cc', 'test/live_sync/single_client_live_preferences_sync_unittest.cc', + 'test/live_sync/two_client_live_autofill_sync_unittest.cc', 'test/live_sync/two_client_live_bookmarks_sync_test.cc', 'test/live_sync/two_client_live_preferences_sync_test.cc', 'test/test_notification_tracker.cc', diff --git a/chrome/test/live_sync/profile_sync_service_test_harness.cc b/chrome/test/live_sync/profile_sync_service_test_harness.cc index 4bcc273..6225cf0 100644 --- a/chrome/test/live_sync/profile_sync_service_test_harness.cc +++ b/chrome/test/live_sync/profile_sync_service_test_harness.cc @@ -137,7 +137,6 @@ bool ProfileSyncServiceTestHarness::RunStateChangeMachine() { EXPECT_LE(last_timestamp_, snap->max_local_timestamp); last_timestamp_ = snap->max_local_timestamp; - SignalStateCompleteWithNextState(WAITING_FOR_NOTHING); break; } diff --git a/chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc b/chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc new file mode 100644 index 0000000..fa33c63 --- /dev/null +++ b/chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc @@ -0,0 +1,275 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <set> +#include <vector> + +#include "base/command_line.h" +#include "base/ref_counted.h" +#include "base/string16.h" +#include "base/string_util.h" +#include "base/waitable_event.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/pref_service.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/browser/webdata/autofill_entry.h" +#include "chrome/browser/webdata/web_database.h" +#include "chrome/browser/webdata/web_data_service.h" +#include "chrome/browser/webdata/web_data_service_test_util.h" +#include "chrome/common/notification_observer_mock.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/live_sync/profile_sync_service_test_harness.h" +#include "chrome/test/live_sync/live_sync_test.h" +#include "chrome/test/thread_observer_helper.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "webkit/glue/form_field.h" + +using base::WaitableEvent; +using testing::_; + +namespace { + +// Define these << operators so we can use EXPECT_EQ with the +// AutofillKeys type. +template<class T1, class T2, class T3> +std::ostream& operator<<(std::ostream& os, const std::set<T1, T2, T3>& seq) { + typedef typename std::set<T1, T2, T3>::const_iterator SetConstIterator; + for (SetConstIterator i = seq.begin(); i != seq.end(); ++i) { + os << *i << ", "; + } + return os; +} + +std::ostream& operator<<(std::ostream& os, const AutofillKey& key) { + return os << UTF16ToUTF8(key.name()) << ", " << UTF16ToUTF8(key.value()); +} + +class GetAllAutofillEntries + : public base::RefCountedThreadSafe<GetAllAutofillEntries> { + public: + explicit GetAllAutofillEntries(WebDataService* web_data_service) + : web_data_service_(web_data_service), + done_event_(false, false) {} + + void Init() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + ChromeThread::PostTask( + ChromeThread::DB, + FROM_HERE, + NewRunnableMethod(this, &GetAllAutofillEntries::Run)); + done_event_.Wait(); + } + + const std::vector<AutofillEntry>& entries() const { + return entries_; + } + + private: + friend class base::RefCountedThreadSafe<GetAllAutofillEntries>; + + void Run() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); + web_data_service_->GetDatabase()->GetAllAutofillEntries(&entries_); + done_event_.Signal(); + } + + WebDataService* web_data_service_; + base::WaitableEvent done_event_; + std::vector<AutofillEntry> entries_; +}; + +ACTION_P(SignalEvent, event) { + event->Signal(); +} + +class AutofillDBThreadObserverHelper : public DBThreadObserverHelper { + protected: + virtual void RegisterObservers() { + registrar_.Add(&observer_, + NotificationType::AUTOFILL_ENTRIES_CHANGED, + NotificationService::AllSources()); + registrar_.Add(&observer_, + NotificationType::AUTOFILL_PROFILE_CHANGED, + NotificationService::AllSources()); + } +}; + +} // namespace; + +class TwoClientLiveAutofillSyncTest : public LiveSyncTest { + public: + typedef std::set<AutofillKey> AutofillKeys; + TwoClientLiveAutofillSyncTest() + : name1_(ASCIIToUTF16("name1")), + name2_(ASCIIToUTF16("name2")), + value1_(ASCIIToUTF16("value1")), + value2_(ASCIIToUTF16("value2")), + done_event1_(false, false), + done_event2_(false, false) { + // This makes sure browser is visible and active while running test. + InProcessBrowserTest::set_show_window(true); + // Set the initial timeout value to 5 min. + InProcessBrowserTest::SetInitialTimeoutInMS(300000); + } + ~TwoClientLiveAutofillSyncTest() {} + + protected: + void SetupHarness() { + client1_.reset(new ProfileSyncServiceTestHarness( + browser()->profile(), username_, password_)); + profile2_.reset(MakeProfile(FILE_PATH_LITERAL("client2"))); + client2_.reset(new ProfileSyncServiceTestHarness( + profile2_.get(), username_, password_)); + wds1_ = browser()->profile()->GetWebDataService(Profile::EXPLICIT_ACCESS); + wds2_ = profile2_->GetWebDataService(Profile::EXPLICIT_ACCESS); + } + + void SetupSync() { + EXPECT_TRUE(client1_->SetupSync()); + EXPECT_TRUE(client1_->AwaitSyncCycleCompletion("Initial setup 1")); + EXPECT_TRUE(client2_->SetupSync()); + EXPECT_TRUE(client2_->AwaitSyncCycleCompletion("Initial setup 2")); + } + + void Cleanup() { + client2_.reset(); + profile2_.reset(); + } + + void AddToWds(WebDataService* wds, const AutofillKeys& keys) { + std::vector<webkit_glue::FormField> form_fields; + for (AutofillKeys::const_iterator i = keys.begin(); i != keys.end(); ++i) { + form_fields.push_back( + webkit_glue::FormField(string16(), + (*i).name(), + (*i).value(), + string16())); + } + + WaitableEvent done_event(false, false); + scoped_refptr<AutofillDBThreadObserverHelper> observer_helper( + new AutofillDBThreadObserverHelper()); + observer_helper->Init(); + + EXPECT_CALL(*observer_helper->observer(), Observe(_, _, _)). + WillOnce(SignalEvent(&done_event)); + wds->AddFormFields(form_fields); + done_event.Wait(); + } + + void GetAllAutofillKeys(WebDataService* wds, AutofillKeys* keys) { + scoped_refptr<GetAllAutofillEntries> get_all_entries = + new GetAllAutofillEntries(wds); + get_all_entries->Init(); + const std::vector<AutofillEntry>& entries = get_all_entries->entries(); + + for (size_t i = 0; i < entries.size(); ++i) { + keys->insert(entries[i].key()); + } + } + + ProfileSyncServiceTestHarness* client1() { return client1_.get(); } + ProfileSyncServiceTestHarness* client2() { return client2_.get(); } + + PrefService* prefs1() { return browser()->profile()->GetPrefs(); } + PrefService* prefs2() { return profile2_->GetPrefs(); } + + string16 name1_; + string16 name2_; + string16 value1_; + string16 value2_; + base::WaitableEvent done_event1_; + base::WaitableEvent done_event2_; + + scoped_ptr<ProfileSyncServiceTestHarness> client1_; + scoped_ptr<ProfileSyncServiceTestHarness> client2_; + scoped_ptr<Profile> profile2_; + WebDataService* wds1_; + WebDataService* wds2_; + + DISALLOW_COPY_AND_ASSIGN(TwoClientLiveAutofillSyncTest); +}; + +IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, Client1HasData) { + SetupHarness(); + + AutofillKeys keys; + keys.insert(AutofillKey("name1", "value1")); + keys.insert(AutofillKey("name1", "value2")); + keys.insert(AutofillKey("name2", "value3")); + keys.insert(AutofillKey("Sigur R\u00F3s", "\u00C1g\u00E6tis byrjun")); + AddToWds(wds1_, keys); + + SetupSync(); + + AutofillKeys wd2_keys; + GetAllAutofillKeys(wds2_, &wd2_keys); + EXPECT_EQ(keys, wd2_keys); + + Cleanup(); +} + +IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, BothHaveData) { + SetupHarness(); + + AutofillKeys keys1; + keys1.insert(AutofillKey("name1", "value1")); + keys1.insert(AutofillKey("name1", "value2")); + keys1.insert(AutofillKey("name2", "value3")); + AddToWds(wds1_, keys1); + + AutofillKeys keys2; + keys2.insert(AutofillKey("name1", "value2")); + keys2.insert(AutofillKey("name2", "value3")); + keys2.insert(AutofillKey("name3", "value4")); + keys2.insert(AutofillKey("name4", "value4")); + AddToWds(wds2_, keys2); + + SetupSync(); + // Wait for client1 to get the new keys from client2. + EXPECT_TRUE(client1()->AwaitSyncCycleCompletion("sync cycle")); + + AutofillKeys expected_keys; + expected_keys.insert(AutofillKey("name1", "value1")); + expected_keys.insert(AutofillKey("name1", "value2")); + expected_keys.insert(AutofillKey("name2", "value3")); + expected_keys.insert(AutofillKey("name3", "value4")); + expected_keys.insert(AutofillKey("name4", "value4")); + + AutofillKeys wd1_keys; + GetAllAutofillKeys(wds1_, &wd1_keys); + EXPECT_EQ(expected_keys, wd1_keys); + + AutofillKeys wd2_keys; + GetAllAutofillKeys(wds2_, &wd2_keys); + EXPECT_EQ(expected_keys, wd2_keys); + + Cleanup(); +} + +IN_PROC_BROWSER_TEST_F(TwoClientLiveAutofillSyncTest, Steady) { + SetupHarness(); + SetupSync(); + + AutofillKeys add_one_key; + add_one_key.insert(AutofillKey("name1", "value1")); + AddToWds(wds1_, add_one_key); + + AutofillKeys expected_keys; + expected_keys.insert(AutofillKey("name1", "value1")); + + EXPECT_TRUE(client1()->AwaitMutualSyncCycleCompletion(client2())); + + AutofillKeys keys; + GetAllAutofillKeys(wds1_, &keys); + EXPECT_EQ(expected_keys, keys); + keys.clear(); + GetAllAutofillKeys(wds2_, &keys); + EXPECT_EQ(expected_keys, keys); + + Cleanup(); +} diff --git a/chrome/test/thread_observer_helper.h b/chrome/test/thread_observer_helper.h new file mode 100644 index 0000000..b8ccc04 --- /dev/null +++ b/chrome/test/thread_observer_helper.h @@ -0,0 +1,70 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_THREAD_OBSERVER_HELPER_H__ +#define CHROME_TEST_THREAD_OBSERVER_HELPER_H__ + +#include "base/ref_counted.h" +#include "base/waitable_event.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/common/notification_observer_mock.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/common/notification_service.h" + +// Helper class to add and remove observers on a non-UI thread from +// the UI thread. +template <class T, typename Traits> +class ThreadObserverHelper : public base::RefCountedThreadSafe<T, Traits> { + public: + explicit ThreadObserverHelper(ChromeThread::ID id) + : id_(id), done_event_(false, false) {} + + void Init() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + ChromeThread::PostTask( + id_, + FROM_HERE, + NewRunnableMethod(this, &ThreadObserverHelper::RegisterObserversTask)); + done_event_.Wait(); + } + + virtual ~ThreadObserverHelper() { + DCHECK(ChromeThread::CurrentlyOn(id_)); + registrar_.RemoveAll(); + } + + NotificationObserverMock* observer() { + return &observer_; + } + + protected: + friend class base::RefCountedThreadSafe<T>; + + virtual void RegisterObservers() = 0; + + NotificationRegistrar registrar_; + NotificationObserverMock observer_; + + private: + void RegisterObserversTask() { + DCHECK(ChromeThread::CurrentlyOn(id_)); + RegisterObservers(); + done_event_.Signal(); + } + + ChromeThread::ID id_; + base::WaitableEvent done_event_; +}; + +class DBThreadObserverHelper; +typedef ThreadObserverHelper< + DBThreadObserverHelper, + ChromeThread::DeleteOnDBThread> DBThreadObserverHelperBase; + +class DBThreadObserverHelper : public DBThreadObserverHelperBase { + public: + DBThreadObserverHelper() : DBThreadObserverHelperBase(ChromeThread::DB) {} +}; + +#endif // CHROME_TEST_THREAD_OBSERVER_HELPER_H__ |