summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorskrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-30 17:07:40 +0000
committerskrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-30 17:07:40 +0000
commitde326e142065a56afd98b6c4e0e155c88d2690f3 (patch)
tree4fb7a52f26cd26708553cf7f78c11e3bf5f07c34
parent7154e601b5a4d530ecc4ce0bfa13554b31d90444 (diff)
downloadchromium_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.cc2
-rw-r--r--chrome/browser/sync/glue/autofill_change_processor.cc8
-rw-r--r--chrome/browser/sync/profile_sync_service_autofill_unittest.cc22
-rw-r--r--chrome/browser/sync/profile_sync_test_util.h21
-rw-r--r--chrome/browser/webdata/autofill_entry.h6
-rw-r--r--chrome/browser/webdata/web_data_service.cc7
-rw-r--r--chrome/browser/webdata/web_data_service_test_util.h43
-rw-r--r--chrome/browser/webdata/web_data_service_unittest.cc81
-rw-r--r--chrome/chrome_tests.gypi4
-rw-r--r--chrome/test/live_sync/profile_sync_service_test_harness.cc1
-rw-r--r--chrome/test/live_sync/two_client_live_autofill_sync_unittest.cc275
-rw-r--r--chrome/test/thread_observer_helper.h70
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__