• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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