1 // Copyright (c) 2012 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_PROFILE_SYNC_SERVICE_HARNESS_H_ 6 #define CHROME_BROWSER_SYNC_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/retry_verifier.h" 17 #include "sync/internal_api/public/base/model_type.h" 18 19 class Profile; 20 21 namespace invalidation { 22 class P2PInvalidationService; 23 } 24 25 namespace browser_sync { 26 namespace sessions { 27 class SyncSessionSnapshot; 28 } 29 } 30 31 // An instance of this class is basically our notion of a "sync client" for 32 // automation purposes. It harnesses the ProfileSyncService member of the 33 // profile passed to it on construction and automates certain things like setup 34 // and authentication. It provides ways to "wait" adequate periods of time for 35 // several clients to get to the same state. 36 class ProfileSyncServiceHarness 37 : public ProfileSyncServiceObserver, 38 public browser_sync::MigrationObserver { 39 public: 40 static ProfileSyncServiceHarness* Create( 41 Profile* profile, 42 const std::string& username, 43 const std::string& password); 44 45 static ProfileSyncServiceHarness* CreateForIntegrationTest( 46 Profile* profile, 47 const std::string& username, 48 const std::string& password, 49 invalidation::P2PInvalidationService* invalidation_service); 50 51 virtual ~ProfileSyncServiceHarness(); 52 53 // Sets the GAIA credentials with which to sign in to sync. 54 void SetCredentials(const std::string& username, const std::string& password); 55 56 // Returns true if sync has been enabled on |profile_|. 57 bool IsSyncAlreadySetup(); 58 59 // Creates a ProfileSyncService for the profile passed at construction and 60 // enables sync for all available datatypes. Returns true only after sync has 61 // been fully initialized and authenticated, and we are ready to process 62 // changes. 63 bool SetupSync(); 64 65 // Same as the above method, but enables sync only for the datatypes contained 66 // in |synced_datatypes|. 67 bool SetupSync(syncer::ModelTypeSet synced_datatypes); 68 69 // ProfileSyncServiceObserver implementation. 70 virtual void OnStateChanged() OVERRIDE; 71 virtual void OnSyncCycleCompleted() OVERRIDE; 72 73 // MigrationObserver implementation. 74 virtual void OnMigrationStateChange() OVERRIDE; 75 76 // Blocks the caller until the sync backend host associated with this harness 77 // has been initialized. Returns true if the wait was successful. 78 bool AwaitBackendInitialized(); 79 80 // Blocks the caller until this harness has completed a single sync cycle 81 // since the previous one. Returns true if a sync cycle has completed. 82 bool AwaitDataSyncCompletion(const std::string& reason); 83 84 // Blocks the caller until this harness has completed as many sync cycles as 85 // are required to ensure its progress marker matches the latest available on 86 // the server. 87 // 88 // Note: When other clients are committing changes this will not be reliable. 89 // If your test involves changes to multiple clients, you should use one of 90 // the other Await* functions, such as AwaitMutualSyncCycleComplete. Refer to 91 // the documentation of those functions for more details. 92 bool AwaitFullSyncCompletion(const std::string& reason); 93 94 // Blocks the caller until sync has been disabled for this client. Returns 95 // true if sync is disabled. 96 bool AwaitSyncDisabled(const std::string& reason); 97 98 // Blocks the caller until exponential backoff has been verified to happen. 99 bool AwaitExponentialBackoffVerification(); 100 101 // Blocks the caller until the syncer receives an actionable error. 102 // Returns true if the sync client received an actionable error. 103 bool AwaitActionableError(); 104 105 // Blocks until the given set of data types are migrated. 106 bool AwaitMigration(syncer::ModelTypeSet expected_migrated_types); 107 108 // Blocks the caller until this harness has observed that the sync engine 109 // has downloaded all the changes seen by the |partner| harness's client. 110 bool WaitUntilProgressMarkersMatch( 111 ProfileSyncServiceHarness* partner, const std::string& reason); 112 113 // Calling this acts as a barrier and blocks the caller until |this| and 114 // |partner| have both completed a sync cycle. When calling this method, 115 // the |partner| should be the passive responder who responds to the actions 116 // of |this|. This method relies upon the synchronization of callbacks 117 // from the message queue. Returns true if two sync cycles have completed. 118 // Note: Use this method when exactly one client makes local change(s), and 119 // exactly one client is waiting to receive those changes. 120 bool AwaitMutualSyncCycleCompletion(ProfileSyncServiceHarness* partner); 121 122 // Blocks the caller until |this| completes its ongoing sync cycle and every 123 // other client in |partners| have achieved identical download progresses. 124 // Note: Use this method when exactly one client makes local change(s), 125 // and more than one client is waiting to receive those changes. 126 bool AwaitGroupSyncCycleCompletion( 127 std::vector<ProfileSyncServiceHarness*>& partners); 128 129 // Blocks the caller until every client in |clients| completes its ongoing 130 // sync cycle and all the clients' progress markers match. Note: Use this 131 // method when more than one client makes local change(s), and more than one 132 // client is waiting to receive those changes. 133 static bool AwaitQuiescence( 134 std::vector<ProfileSyncServiceHarness*>& clients); 135 136 // Blocks the caller until |service_| indicates that a passphrase is required. 137 bool AwaitPassphraseRequired(); 138 139 // Blocks the caller until |service_| indicates that the passphrase set by 140 // calling SetDecryptionPassphrase has been accepted. 141 bool AwaitPassphraseAccepted(); 142 143 // Returns the ProfileSyncService member of the sync client. 144 ProfileSyncService* service() { return service_; } 145 146 // Returns the status of the ProfileSyncService member of the sync client. 147 ProfileSyncService::Status GetStatus(); 148 149 // See ProfileSyncService::ShouldPushChanges(). 150 bool ServiceIsPushingChanges() { return service_->ShouldPushChanges(); } 151 152 // Enables sync for a particular sync datatype. Returns true on success. 153 bool EnableSyncForDatatype(syncer::ModelType datatype); 154 155 // Disables sync for a particular sync datatype. Returns true on success. 156 bool DisableSyncForDatatype(syncer::ModelType datatype); 157 158 // Enables sync for all sync datatypes. Returns true on success. 159 bool EnableSyncForAllDatatypes(); 160 161 // Disables sync for all sync datatypes. Returns true on success. 162 bool DisableSyncForAllDatatypes(); 163 164 // Returns a snapshot of the current sync session. 165 syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const; 166 167 // Encrypt the datatype |type|. This method will block while the sync backend 168 // host performs the encryption or a timeout is reached. 169 // PostCondition: 170 // returns: True if |type| was encrypted and we are fully synced. 171 // False if we timed out. 172 bool EnableEncryptionForType(syncer::ModelType type); 173 174 // Wait until |type| is encrypted or we time out. 175 // PostCondition: 176 // returns: True if |type| is currently encrypted and we are fully synced. 177 // False if we timed out. 178 bool WaitForTypeEncryption(syncer::ModelType type); 179 180 // Check if |type| is encrypted. 181 bool IsTypeEncrypted(syncer::ModelType type); 182 183 // Check if |type| is registered and the controller is running. 184 bool IsTypeRunning(syncer::ModelType type); 185 186 // Check if |type| is being synced. 187 bool IsTypePreferred(syncer::ModelType type); 188 189 // Get the number of sync entries this client has. This includes all top 190 // level or permanent items, and can include recently deleted entries. 191 size_t GetNumEntries() const; 192 193 // Get the number of sync datatypes registered (ignoring whatever state 194 // they're in). 195 size_t GetNumDatatypes() const; 196 197 // Gets the |auto_start_enabled_| variable from the |service_|. 198 bool AutoStartEnabled(); 199 200 // Returns true if a status change took place, false on timeout. 201 bool AwaitStatusChangeWithTimeout(int timeout_milliseconds, 202 const std::string& reason); 203 204 private: 205 friend class StateChangeTimeoutEvent; 206 207 enum WaitState { 208 // The sync client has just been initialized. 209 INITIAL_WAIT_STATE = 0, 210 211 // The sync client awaits the OnBackendInitialized() callback. 212 WAITING_FOR_ON_BACKEND_INITIALIZED, 213 214 // The sync client is waiting for the first sync cycle to complete. 215 WAITING_FOR_INITIAL_SYNC, 216 217 // The sync client is waiting for data to be synced. 218 WAITING_FOR_DATA_SYNC, 219 220 // The sync client is waiting for data and progress markers to be synced. 221 WAITING_FOR_FULL_SYNC, 222 223 // The sync client anticipates incoming updates leading to a new sync cycle. 224 WAITING_FOR_UPDATES, 225 226 // The sync client is waiting for a passphrase to be required by the 227 // cryptographer. 228 WAITING_FOR_PASSPHRASE_REQUIRED, 229 230 // The sync client is waiting for its passphrase to be accepted by the 231 // cryptographer. 232 WAITING_FOR_PASSPHRASE_ACCEPTED, 233 234 // The sync client anticipates encryption of new datatypes. 235 WAITING_FOR_ENCRYPTION, 236 237 // The sync client is waiting for the datatype manager to be configured and 238 // for sync to be fully initialized. Used after a browser restart, where a 239 // full sync cycle is not expected to occur. 240 WAITING_FOR_SYNC_CONFIGURATION, 241 242 // The sync client is waiting for sync to be disabled for this client. 243 WAITING_FOR_SYNC_DISABLED, 244 245 // The sync client is in the exponential backoff mode. Verify that 246 // backoffs are triggered correctly. 247 WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION, 248 249 // The sync client is waiting for migration to start. 250 WAITING_FOR_MIGRATION_TO_START, 251 252 // The sync client is waiting for migration to finish. 253 WAITING_FOR_MIGRATION_TO_FINISH, 254 255 // The sync client is waiting for an actionable error from the server. 256 WAITING_FOR_ACTIONABLE_ERROR, 257 258 // The client verification is complete. We don't care about the state of 259 // the syncer any more. 260 WAITING_FOR_NOTHING, 261 262 // The sync client needs a passphrase in order to decrypt data. 263 SET_PASSPHRASE_FAILED, 264 265 // The sync client's credentials were rejected. 266 CREDENTIALS_REJECTED, 267 268 // The sync client cannot reach the server. 269 SERVER_UNREACHABLE, 270 271 // The sync client is fully synced and there are no pending updates. 272 FULLY_SYNCED, 273 274 // Syncing is disabled for the client. 275 SYNC_DISABLED, 276 277 NUMBER_OF_STATES, 278 }; 279 280 ProfileSyncServiceHarness( 281 Profile* profile, 282 const std::string& username, 283 const std::string& password, 284 invalidation::P2PInvalidationService* invalidation_service); 285 286 // Listen to migration events if the migrator has been initialized 287 // and we're not already listening. Returns true if we started 288 // listening. 289 bool TryListeningToMigrationEvents(); 290 291 // Called from the observer when the current wait state has been completed. 292 void SignalStateCompleteWithNextState(WaitState next_state); 293 294 // Indicates that the operation being waited on is complete. 295 void SignalStateComplete(); 296 297 // Finite state machine for controlling state. Returns true only if a state 298 // change has taken place. 299 bool RunStateChangeMachine(); 300 301 // A helper for implementing IsDataSynced() and IsFullySynced(). 302 bool IsDataSyncedImpl( 303 const syncer::sessions::SyncSessionSnapshot& snapshot); 304 305 // Returns true if the sync client has no unsynced items. 306 bool IsDataSynced(); 307 308 // Returns true if the sync client has no unsynced items and its progress 309 // markers are believed to be up to date. 310 // 311 // Although we can't detect when commits from other clients invalidate our 312 // local progress markers, we do know when our own commits have invalidated 313 // our timestmaps. This check returns true when this client has, to the best 314 // of its knowledge, downloaded the latest progress markers. 315 bool IsFullySynced(); 316 317 // Returns true if there is a backend migration in progress. 318 bool HasPendingBackendMigration(); 319 320 // Returns true if this client has downloaded all the items that the 321 // other client has. 322 bool MatchesOtherClient(ProfileSyncServiceHarness* partner); 323 324 // Returns a string with relevant info about client's sync state (if 325 // available), annotated with |message|. Useful for logging. 326 std::string GetClientInfoString(const std::string& message); 327 328 // Gets the current progress marker of the current sync session for a 329 // particular datatype. Returns an empty string if the progress marker isn't 330 // found. 331 std::string GetSerializedProgressMarker(syncer::ModelType model_type) const; 332 333 // Gets detailed status from |service_| in pretty-printable form. 334 std::string GetServiceStatus(); 335 336 // When in WAITING_FOR_ENCRYPTION state, we check to see if this type is now 337 // encrypted to determine if we're done. 338 syncer::ModelType waiting_for_encryption_type_; 339 340 // The WaitState in which the sync client currently is. Helps determine what 341 // action to take when RunStateChangeMachine() is called. 342 WaitState wait_state_; 343 344 // Sync profile associated with this sync client. 345 Profile* profile_; 346 347 // ProfileSyncService object associated with |profile_|. 348 ProfileSyncService* service_; 349 350 // P2PInvalidationService associated with |profile_|. 351 invalidation::P2PInvalidationService* p2p_invalidation_service_; 352 353 // The harness of the client whose update progress marker we're expecting 354 // eventually match. 355 ProfileSyncServiceHarness* progress_marker_partner_; 356 357 // Credentials used for GAIA authentication. 358 std::string username_; 359 std::string password_; 360 361 // The current set of data types pending migration. Used by 362 // AwaitMigration(). 363 syncer::ModelTypeSet pending_migration_types_; 364 365 // The set of data types that have undergone migration. Used by 366 // AwaitMigration(). 367 syncer::ModelTypeSet migrated_types_; 368 369 // Used for logging. 370 const std::string profile_debug_name_; 371 372 // Keeps track of the number of attempts at exponential backoff and its 373 // related bookkeeping information for verification. 374 browser_sync::RetryVerifier retry_verifier_; 375 376 // Flag set to true when we're waiting for a status change to happen. Used to 377 // avoid triggering internal state machine logic on unexpected sync observer 378 // callbacks. 379 bool waiting_for_status_change_; 380 381 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceHarness); 382 }; 383 384 #endif // CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_HARNESS_H_ 385