Home | History | Annotate | Download | only in integration
      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.
    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().
    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