summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync
diff options
context:
space:
mode:
authorrsimha@chromium.org <rsimha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-03 23:27:31 +0000
committerrsimha@chromium.org <rsimha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-03 23:27:31 +0000
commit909a81eaa4568f4b13562dc3f34ac7268b590f09 (patch)
tree958829ea557102634d623123a77f0ae20a7dd6da /chrome/browser/sync
parentc09fb1c79c0a3e76dbb6091e4b718fd9bb197395 (diff)
downloadchromium_src-909a81eaa4568f4b13562dc3f34ac7268b590f09.zip
chromium_src-909a81eaa4568f4b13562dc3f34ac7268b590f09.tar.gz
chromium_src-909a81eaa4568f4b13562dc3f34ac7268b590f09.tar.bz2
PyAuto hooks for Sync in TestingAutomationProvider
This patch exposes hooks for sync in TestingAutomationProvider that the chrome pyauto test suite can use. It contains the following changes: - Partial revert of an earlier change to ProfileSyncServiceHarness. Some of its methods were made pure virtual, but this ended up being unnecessary. Also ripped out unnecessary code from LiveSyncTest. - Minor refactor of ProfileSyncServiceHarness to allow for scenarios where the browser is restarted. - A bunch of new methods in TestingAutomationProvider: SignInToSync, GetSyncInfo, AwaitSyncCycleCompletion, EnableSyncForDatatypes and DisableSyncForDatatypes. - A new method in model_type.h/cc called ModelTypeFromString. Required for automation. - New APIs in pyauto.py for sync. - New test suite sync.py with sample tests. BUG=53651, 60970, 56460, 61639 TEST=run pyauto sync tests Review URL: http://codereview.chromium.org/4096004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64988 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/sync')
-rw-r--r--chrome/browser/sync/profile_sync_service_harness.cc86
-rw-r--r--chrome/browser/sync/profile_sync_service_harness.h41
-rw-r--r--chrome/browser/sync/syncable/model_type.cc30
-rw-r--r--chrome/browser/sync/syncable/model_type.h4
4 files changed, 119 insertions, 42 deletions
diff --git a/chrome/browser/sync/profile_sync_service_harness.cc b/chrome/browser/sync/profile_sync_service_harness.cc
index 3ecafb7..4750033 100644
--- a/chrome/browser/sync/profile_sync_service_harness.cc
+++ b/chrome/browser/sync/profile_sync_service_harness.cc
@@ -84,18 +84,44 @@ bool StateChangeTimeoutEvent::Abort() {
}
ProfileSyncServiceHarness::ProfileSyncServiceHarness(
- Profile* p,
+ Profile* profile,
const std::string& username,
const std::string& password,
int id)
- : wait_state_(WAITING_FOR_ON_BACKEND_INITIALIZED),
- profile_(p),
+ : wait_state_(INITIAL_WAIT_STATE),
+ profile_(profile),
service_(NULL),
last_timestamp_(0),
min_timestamp_needed_(kMinTimestampNeededNone),
username_(username),
password_(password),
- id_(id) {}
+ id_(id) {
+ if (IsSyncAlreadySetup()) {
+ service_ = profile_->GetProfileSyncService();
+ service_->AddObserver(this);
+ wait_state_ = FULLY_SYNCED;
+ }
+}
+
+// static
+ProfileSyncServiceHarness* ProfileSyncServiceHarness::CreateAndAttach(
+ Profile* profile) {
+ if (!profile->HasProfileSyncService()) {
+ NOTREACHED() << "Profile has never signed into sync.";
+ return NULL;
+ }
+ return new ProfileSyncServiceHarness(profile, "", "", 0);
+}
+
+void ProfileSyncServiceHarness::SetCredentials(const std::string& username,
+ const std::string& password) {
+ username_ = username;
+ password_ = password;
+}
+
+bool ProfileSyncServiceHarness::IsSyncAlreadySetup() {
+ return profile_->HasProfileSyncService();
+}
bool ProfileSyncServiceHarness::SetupSync() {
syncable::ModelTypeSet synced_datatypes;
@@ -109,7 +135,7 @@ bool ProfileSyncServiceHarness::SetupSync() {
bool ProfileSyncServiceHarness::SetupSync(
const syncable::ModelTypeSet& synced_datatypes) {
// Initialize the sync client's profile sync service object.
- service_ = profile_->GetProfileSyncService("");
+ service_ = profile_->GetProfileSyncService();
if (service_ == NULL) {
LOG(ERROR) << "SetupSync(): service_ is null.";
return false;
@@ -123,7 +149,7 @@ bool ProfileSyncServiceHarness::SetupSync(
service_->signin()->StartSignIn(username_, password_, "", "");
// Wait for the OnBackendInitialized() callback.
- DCHECK_EQ(wait_state_, WAITING_FOR_ON_BACKEND_INITIALIZED);
+ wait_state_ = WAITING_FOR_ON_BACKEND_INITIALIZED;
if (!AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs,
"Waiting for OnBackendInitialized().")) {
LOG(ERROR) << "OnBackendInitialized() not seen after "
@@ -148,6 +174,9 @@ bool ProfileSyncServiceHarness::SetupSync(
return false;
}
+ // Indicate to the browser that sync setup is complete.
+ service()->SetSyncSetupCompleted();
+
return true;
}
@@ -157,6 +186,10 @@ void ProfileSyncServiceHarness::SignalStateCompleteWithNextState(
SignalStateComplete();
}
+void ProfileSyncServiceHarness::SignalStateComplete() {
+ MessageLoop::current()->Quit();
+}
+
bool ProfileSyncServiceHarness::RunStateChangeMachine() {
WaitState original_wait_state = wait_state_;
switch (wait_state_) {
@@ -353,13 +386,16 @@ bool ProfileSyncServiceHarness::AwaitStatusChangeWithTimeout(
}
scoped_refptr<StateChangeTimeoutEvent> timeout_signal(
new StateChangeTimeoutEvent(this, reason));
- MessageLoopForUI* loop = MessageLoopForUI::current();
+ MessageLoop* loop = MessageLoop::current();
+ bool did_allow_nestable_tasks = loop->NestableTasksAllowed();
+ loop->SetNestableTasksAllowed(true);
loop->PostDelayedTask(
FROM_HERE,
NewRunnableMethod(timeout_signal.get(),
&StateChangeTimeoutEvent::Callback),
timeout_milliseconds);
- AwaitStatusChange();
+ loop->Run();
+ loop->SetNestableTasksAllowed(did_allow_nestable_tasks);
LogClientInfo("AwaitStatusChangeWithTimeout succeeded");
return timeout_signal->Abort();
}
@@ -370,11 +406,12 @@ ProfileSyncService::Status ProfileSyncServiceHarness::GetStatus() {
}
bool ProfileSyncServiceHarness::IsSynced() {
+ if (service() == NULL)
+ return false;
const SyncSessionSnapshot* snap = GetLastSessionSnapshot();
// TODO(rsimha): Remove additional checks of snap->has_more_to_sync and
// snap->unsynced_count once http://crbug.com/48989 is fixed.
- return (service() &&
- snap &&
+ return (snap &&
ServiceIsPushingChanges() &&
GetStatus().notifications_enabled &&
!service()->backend()->HasUnsyncedItems() &&
@@ -478,19 +515,24 @@ int64 ProfileSyncServiceHarness::GetUpdatedTimestamp() {
}
void ProfileSyncServiceHarness::LogClientInfo(std::string message) {
- const SyncSessionSnapshot* snap = GetLastSessionSnapshot();
- if (snap) {
- VLOG(1) << "Client " << id_ << ": " << message
- << ": max_local_timestamp: " << snap->max_local_timestamp
- << ", has_more_to_sync: " << snap->has_more_to_sync
- << ", unsynced_count: " << snap->unsynced_count
- << ", has_unsynced_items: "
- << service()->backend()->HasUnsyncedItems()
- << ", notifications_enabled: "
- << GetStatus().notifications_enabled
- << ", service_is_pushing_changes: " << ServiceIsPushingChanges();
+ if (service()) {
+ const SyncSessionSnapshot* snap = GetLastSessionSnapshot();
+ if (snap) {
+ VLOG(1) << "Client " << id_ << ": " << message
+ << ": max_local_timestamp: " << snap->max_local_timestamp
+ << ", has_more_to_sync: " << snap->has_more_to_sync
+ << ", unsynced_count: " << snap->unsynced_count
+ << ", has_unsynced_items: "
+ << service()->backend()->HasUnsyncedItems()
+ << ", notifications_enabled: "
+ << GetStatus().notifications_enabled
+ << ", service_is_pushing_changes: " << ServiceIsPushingChanges();
+ } else {
+ VLOG(1) << "Client " << id_ << ": " << message
+ << ": Sync session snapshot not available.";
+ }
} else {
VLOG(1) << "Client " << id_ << ": " << message
- << ": Sync session snapshot not available.";
+ << ": Sync service not available.";
}
}
diff --git a/chrome/browser/sync/profile_sync_service_harness.h b/chrome/browser/sync/profile_sync_service_harness.h
index 90f4540..a50bb8a 100644
--- a/chrome/browser/sync/profile_sync_service_harness.h
+++ b/chrome/browser/sync/profile_sync_service_harness.h
@@ -20,18 +20,27 @@ class Profile;
// automation purposes. It harnesses the ProfileSyncService member of the
// profile passed to it on construction and automates certain things like setup
// and authentication. It provides ways to "wait" adequate periods of time for
-// several clients to get to the same state. In order to use this class for
-// automation, derived classes must implement 2 methods: SignalStateComplete()
-// and AwaitStatusChange().
+// several clients to get to the same state.
class ProfileSyncServiceHarness : public ProfileSyncServiceObserver {
public:
- ProfileSyncServiceHarness(Profile* p,
+ ProfileSyncServiceHarness(Profile* profile,
const std::string& username,
const std::string& password,
int id);
virtual ~ProfileSyncServiceHarness() {}
+ // Creates a ProfileSyncServiceHarness object and attaches it to |profile|, a
+ // profile that is assumed to have been signed into sync in the past. Caller
+ // takes ownership.
+ static ProfileSyncServiceHarness* CreateAndAttach(Profile* profile);
+
+ // Sets the GAIA credentials with which to sign in to sync.
+ void SetCredentials(const std::string& username, const std::string& password);
+
+ // Returns true if sync has been enabled on |profile_|.
+ bool IsSyncAlreadySetup();
+
// Creates a ProfileSyncService for the profile passed at construction and
// enables sync for all available datatypes. Returns true only after sync has
// been fully initialized and authenticated, and we are ready to process
@@ -109,8 +118,11 @@ class ProfileSyncServiceHarness : public ProfileSyncServiceObserver {
friend class StateChangeTimeoutEvent;
enum WaitState {
+ // The sync client has just been initialized.
+ INITIAL_WAIT_STATE = 0,
+
// The sync client awaits the OnBackendInitialized() callback.
- WAITING_FOR_ON_BACKEND_INITIALIZED = 0,
+ WAITING_FOR_ON_BACKEND_INITIALIZED,
// The sync client is waiting for the first sync cycle to complete.
WAITING_FOR_INITIAL_SYNC,
@@ -139,10 +151,8 @@ class ProfileSyncServiceHarness : public ProfileSyncServiceObserver {
// Called from the observer when the current wait state has been completed.
void SignalStateCompleteWithNextState(WaitState next_state);
- // Indicates that the operation being waited on is complete. Derived classes
- // may implement this either by quitting the UI message loop, or by signaling
- // a WaitableEvent object.
- virtual void SignalStateComplete() = 0;
+ // Indicates that the operation being waited on is complete.
+ void SignalStateComplete();
// Finite state machine for controlling state. Returns true only if a state
// change has taken place.
@@ -152,26 +162,21 @@ class ProfileSyncServiceHarness : public ProfileSyncServiceObserver {
bool AwaitStatusChangeWithTimeout(int timeout_milliseconds,
const std::string& reason);
- // Waits until the sync client's status changes. Derived classes may implement
- // this either by running the UI message loop, or by waiting on a
- // WaitableEvent object.
- virtual void AwaitStatusChange() = 0;
-
// Returns true if the sync client has no unsynced items.
bool IsSynced();
// Logs message with relevant info about client's sync state (if available).
void LogClientInfo(std::string message);
+ // Updates |last_timestamp_| with the timestamp of the current sync session.
+ // Returns the new value of |last_timestamp_|.
+ int64 GetUpdatedTimestamp();
+
WaitState wait_state_;
Profile* profile_;
ProfileSyncService* service_;
- // Updates |last_timestamp_| with the timestamp of the current sync session.
- // Returns the new value of |last_timestamp_|.
- int64 GetUpdatedTimestamp();
-
// This value tracks the max sync timestamp (e.g. synced-to revision) inside
// the sync engine. It gets updated when a sync cycle ends and the session
// snapshot implies syncing is "done".
diff --git a/chrome/browser/sync/syncable/model_type.cc b/chrome/browser/sync/syncable/model_type.cc
index 5a06be8..2d17ebc 100644
--- a/chrome/browser/sync/syncable/model_type.cc
+++ b/chrome/browser/sync/syncable/model_type.cc
@@ -150,6 +150,33 @@ std::string ModelTypeToString(ModelType model_type) {
}
}
+ModelType ModelTypeFromString(const std::string& model_type_string) {
+ if (model_type_string == "Bookmarks")
+ return BOOKMARKS;
+ else if (model_type_string == "Preferences")
+ return PREFERENCES;
+ else if (model_type_string == "Passwords")
+ return PASSWORDS;
+ else if (model_type_string == "Autofill")
+ return AUTOFILL;
+ else if (model_type_string == "Themes")
+ return THEMES;
+ else if (model_type_string == "Typed URLs")
+ return TYPED_URLS;
+ else if (model_type_string == "Extensions")
+ return EXTENSIONS;
+ else if (model_type_string == "Encryption keys")
+ return NIGORI;
+ else if (model_type_string == "Sessions")
+ return SESSIONS;
+ else if (model_type_string == "Apps")
+ return APPS;
+ else
+ NOTREACHED() << "No known model type corresponding to "
+ << model_type_string << ".";
+ return UNSPECIFIED;
+}
+
// TODO(akalin): Figure out a better way to do these mappings.
namespace {
@@ -247,8 +274,7 @@ bool NotificationTypeToRealModelType(const std::string& notification_type,
} else if (notification_type == kSessionNotificationType) {
*model_type = SESSIONS;
return true;
- }
- else if (notification_type == kUnknownNotificationType) {
+ } else if (notification_type == kUnknownNotificationType) {
// TODO(akalin): This is a hack to make new sync data types work with
// server-issued notifications. Remove this when it's not needed
// anymore.
diff --git a/chrome/browser/sync/syncable/model_type.h b/chrome/browser/sync/syncable/model_type.h
index 077d243..c619b7e 100644
--- a/chrome/browser/sync/syncable/model_type.h
+++ b/chrome/browser/sync/syncable/model_type.h
@@ -89,8 +89,12 @@ ModelType GetModelType(const sync_pb::SyncEntity& sync_entity);
// prefer using GetModelType where possible.
ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics);
+// Returns a string that represents the name of |model_type|.
std::string ModelTypeToString(ModelType model_type);
+// Returns the ModelType corresponding to the name |model_type_string|.
+ModelType ModelTypeFromString(const std::string& model_type_string);
+
// Convert a real model type to a notification type (used for
// subscribing to server-issued notifications). Returns true iff
// |model_type| was a real model type and |notification_type| was