Home | History | Annotate | Download | only in sync
      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