1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_PROFILE_SYNC_SERVICE_HARNESS_H_ 6 #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_PROFILE_SYNC_SERVICE_HARNESS_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/compiler_specific.h" 13 #include "chrome/browser/sync/backend_migrator.h" 14 #include "chrome/browser/sync/profile_sync_service.h" 15 #include "chrome/browser/sync/profile_sync_service_observer.h" 16 #include "chrome/browser/sync/test/integration/retry_verifier.h" 17 #include "sync/internal_api/public/base/model_type.h" 18 19 class Profile; 20 class StatusChangeChecker; 21 22 namespace invalidation { 23 class P2PInvalidationService; 24 } 25 26 namespace browser_sync { 27 namespace sessions { 28 class SyncSessionSnapshot; 29 } 30 } 31 32 // An instance of this class is basically our notion of a "sync client" for 33 // automation purposes. It harnesses the ProfileSyncService member of the 34 // profile passed to it on construction and automates certain things like setup 35 // and authentication. It provides ways to "wait" adequate periods of time for 36 // several clients to get to the same state. 37 class ProfileSyncServiceHarness 38 : public ProfileSyncServiceObserver, 39 public browser_sync::MigrationObserver { 40 public: 41 static ProfileSyncServiceHarness* Create( 42 Profile* profile, 43 const std::string& username, 44 const std::string& password); 45 46 static ProfileSyncServiceHarness* CreateForIntegrationTest( 47 Profile* profile, 48 const std::string& username, 49 const std::string& password, 50 invalidation::P2PInvalidationService* invalidation_service); 51 52 virtual ~ProfileSyncServiceHarness(); 53 54 // Sets the GAIA credentials with which to sign in to sync. 55 void SetCredentials(const std::string& username, const std::string& password); 56 57 // Returns true if exponential backoff is complete. 58 bool IsExponentialBackoffDone() const; 59 60 // Returns true if sync is disabled for this client. 61 bool IsSyncDisabled() const; 62 63 // Returns true if an auth error has been encountered. 64 bool HasAuthError() const; 65 66 // Creates a ProfileSyncService for the profile passed at construction and 67 // enables sync for all available datatypes. Returns true only after sync has 68 // been fully initialized and authenticated, and we are ready to process 69 // changes. 70 bool SetupSync(); 71 72 // Same as the above method, but enables sync only for the datatypes contained 73 // in |synced_datatypes|. 74 bool SetupSync(syncer::ModelTypeSet synced_datatypes); 75 76 // ProfileSyncServiceObserver implementation. 77 virtual void OnStateChanged() OVERRIDE; 78 virtual void OnSyncCycleCompleted() OVERRIDE; 79 80 // MigrationObserver implementation. 81 virtual void OnMigrationStateChange() OVERRIDE; 82 83 // Blocks the caller until the sync backend host associated with this harness 84 // has been initialized. Returns true if the wait was successful. 85 bool AwaitBackendInitialized(); 86 87 // Blocks the caller until this harness has completed a single sync cycle 88 // since the previous one. Returns true if a sync cycle has completed. 89 bool AwaitDataSyncCompletion(); 90 91 // Blocks the caller until this harness has completed as many sync cycles as 92 // are required to ensure its progress marker matches the latest available on 93 // the server. 94 // 95 // Note: When other clients are committing changes this will not be reliable. 96 // If your test involves changes to multiple clients, you should use one of 97 // the other Await* functions, such as AwaitMutualSyncCycleComplete. Refer to 98 // the documentation of those functions for more details. 99 bool AwaitFullSyncCompletion(); 100 101 // Blocks the caller until sync has been disabled for this client. Returns 102 // true if sync is disabled. 103 bool AwaitSyncDisabled(); 104 105 // Blocks the caller until exponential backoff has been verified to happen. 106 bool AwaitExponentialBackoffVerification(); 107 108 // Blocks the caller until the syncer receives an actionable error. 109 // Returns true if the sync client received an actionable error. 110 bool AwaitActionableError(); 111 112 // Blocks until the given set of data types are migrated. 113 bool AwaitMigration(syncer::ModelTypeSet expected_migrated_types); 114 115 // Blocks the caller until this harness has observed that the sync engine 116 // has downloaded all the changes seen by the |partner| harness's client. 117 bool WaitUntilProgressMarkersMatch(ProfileSyncServiceHarness* partner); 118 119 // Calling this acts as a barrier and blocks the caller until |this| and 120 // |partner| have both completed a sync cycle. When calling this method, 121 // the |partner| should be the passive responder who responds to the actions 122 // of |this|. This method relies upon the synchronization of callbacks 123 // from the message queue. Returns true if two sync cycles have completed. 124 // Note: Use this method when exactly one client makes local change(s), and 125 // exactly one client is waiting to receive those changes. 126 bool AwaitMutualSyncCycleCompletion(ProfileSyncServiceHarness* partner); 127 128 // Blocks the caller until |this| completes its ongoing sync cycle and every 129 // other client in |partners| have achieved identical download progresses. 130 // Note: Use this method when exactly one client makes local change(s), 131 // and more than one client is waiting to receive those changes. 132 bool AwaitGroupSyncCycleCompletion( 133 std::vector<ProfileSyncServiceHarness*>& partners); 134 135 // Blocks the caller until every client in |clients| completes its ongoing 136 // sync cycle and all the clients' progress markers match. Note: Use this 137 // method when more than one client makes local change(s), and more than one 138 // client is waiting to receive those changes. 139 static bool AwaitQuiescence( 140 std::vector<ProfileSyncServiceHarness*>& clients); 141 142 // Blocks the caller until |service_| indicates that a passphrase is required. 143 bool AwaitPassphraseRequired(); 144 145 // Blocks the caller until |service_| indicates that the passphrase set by 146 // calling SetDecryptionPassphrase has been accepted. 147 bool AwaitPassphraseAccepted(); 148 149 // Returns the ProfileSyncService member of the sync client. service()150 ProfileSyncService* service() const { return service_; } 151 152 // Returns the status of the ProfileSyncService member of the sync client. 153 ProfileSyncService::Status GetStatus() const; 154 155 // See ProfileSyncService::ShouldPushChanges(). ServiceIsPushingChanges()156 bool ServiceIsPushingChanges() const { return service_->ShouldPushChanges(); } 157 158 // Enables sync for a particular sync datatype. Returns true on success. 159 bool EnableSyncForDatatype(syncer::ModelType datatype); 160 161 // Disables sync for a particular sync datatype. Returns true on success. 162 bool DisableSyncForDatatype(syncer::ModelType datatype); 163 164 // Enables sync for all sync datatypes. Returns true on success. 165 bool EnableSyncForAllDatatypes(); 166 167 // Disables sync for all sync datatypes. Returns true on success. 168 bool DisableSyncForAllDatatypes(); 169 170 // Returns a snapshot of the current sync session. 171 syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const; 172 173 // Encrypts all datatypes. This method will block while the sync backend host 174 // performs the encryption, or a timeout is reached. Returns true if 175 // encryption is complete and we are fully synced, and false if we timed out. 176 bool EnableEncryption(); 177 178 // Waits until encryption is complete for all datatypes. Returns true if 179 // encryption is complete and we are fully synced, and false if we timed out. 180 bool WaitForEncryption(); 181 182 // Returns true if encryption is complete for all datatypes, and false 183 // otherwise. 184 bool IsEncryptionComplete() const; 185 186 // Check if |type| is registered and the controller is running. 187 bool IsTypeRunning(syncer::ModelType type); 188 189 // Check if |type| is being synced. 190 bool IsTypePreferred(syncer::ModelType type); 191 192 // Returns true if the sync client has no unsynced items. 193 bool IsDataSynced() const; 194 195 // Returns true if the sync client has no unsynced items and its progress 196 // markers are believed to be up to date. 197 // 198 // Although we can't detect when commits from other clients invalidate our 199 // local progress markers, we do know when our own commits have invalidated 200 // our timestmaps. This check returns true when this client has, to the best 201 // of its knowledge, downloaded the latest progress markers. 202 bool IsFullySynced() const; 203 204 // Get the number of sync entries this client has. This includes all top 205 // level or permanent items, and can include recently deleted entries. 206 size_t GetNumEntries() const; 207 208 // Get the number of sync datatypes registered (ignoring whatever state 209 // they're in). 210 size_t GetNumDatatypes() const; 211 212 // Gets the |auto_start_enabled_| variable from the |service_|. 213 bool AutoStartEnabled(); 214 215 // Runs the UI message loop and waits until the Run() method of |checker| 216 // returns true, indicating that the status change we are waiting for has 217 // taken place. Caller retains ownership of |checker|, which must outlive this 218 // method. Returns true if the status change was observed. In case of a 219 // timeout, we log the |source| of the call to this method, and return false. 220 bool AwaitStatusChange(StatusChangeChecker* checker, 221 const std::string& source); 222 223 // Returns a string that can be used as the value of an oauth2 refresh token. 224 // This function guarantees that a different string is returned each time 225 // it is called. 226 std::string GenerateFakeOAuth2RefreshTokenString(); 227 228 // Returns a string with relevant info about client's sync state (if 229 // available), annotated with |message|. Useful for logging. 230 std::string GetClientInfoString(const std::string& message) const; 231 232 // Returns true if this client has downloaded all the items that the 233 // other client has. 234 bool MatchesPartnerClient() const; 235 236 // Returns true if there is a backend migration in progress. 237 bool HasPendingBackendMigration() const; 238 239 private: 240 friend class StateChangeTimeoutEvent; 241 242 ProfileSyncServiceHarness( 243 Profile* profile, 244 const std::string& username, 245 const std::string& password, 246 invalidation::P2PInvalidationService* invalidation_service); 247 248 // Listen to migration events if the migrator has been initialized 249 // and we're not already listening. Returns true if we started 250 // listening. 251 bool TryListeningToMigrationEvents(); 252 253 // Indicates that the operation being waited on is complete. 254 void SignalStateComplete(); 255 256 // A helper for implementing IsDataSynced() and IsFullySynced(). 257 bool IsDataSyncedImpl() const; 258 259 // Signals that sync setup is complete, and that PSS may begin syncing. 260 void FinishSyncSetup(); 261 262 // Gets the current progress marker of the current sync session for a 263 // particular datatype. Returns an empty string if the progress marker isn't 264 // found. 265 std::string GetSerializedProgressMarker(syncer::ModelType model_type) const; 266 267 // Gets detailed status from |service_| in pretty-printable form. 268 std::string GetServiceStatus(); 269 270 // Sync profile associated with this sync client. 271 Profile* profile_; 272 273 // ProfileSyncService object associated with |profile_|. 274 ProfileSyncService* service_; 275 276 // P2PInvalidationService associated with |profile_|. 277 invalidation::P2PInvalidationService* p2p_invalidation_service_; 278 279 // The harness of the client whose update progress marker we're expecting 280 // eventually match. 281 ProfileSyncServiceHarness* progress_marker_partner_; 282 283 // Credentials used for GAIA authentication. 284 std::string username_; 285 std::string password_; 286 287 // Number used by GenerateFakeOAuth2RefreshTokenString() to make sure that 288 // all refresh tokens used in the tests are different. 289 int oauth2_refesh_token_number_; 290 291 // The current set of data types pending migration. Used by 292 // AwaitMigration(). 293 syncer::ModelTypeSet pending_migration_types_; 294 295 // The set of data types that have undergone migration. Used by 296 // AwaitMigration(). 297 syncer::ModelTypeSet migrated_types_; 298 299 // Used for logging. 300 const std::string profile_debug_name_; 301 302 // Keeps track of the state change on which we are waiting. PSSHarness can 303 // wait on only one status change at a time. 304 StatusChangeChecker* status_change_checker_; 305 306 // Keeps track of the number of attempts at exponential backoff and its 307 // related bookkeeping information for verification. 308 scoped_ptr<RetryVerifier> retry_verifier_; 309 310 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceHarness); 311 }; 312 313 #endif // CHROME_BROWSER_SYNC_TEST_INTEGRATION_PROFILE_SYNC_SERVICE_HARNESS_H_ 314