sync_test.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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_SYNC_TEST_H_
6#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/scoped_vector.h"
15#include "chrome/test/base/in_process_browser_test.h"
16#include "net/dns/mock_host_resolver.h"
17#include "net/http/http_status_code.h"
18#include "net/url_request/url_request_status.h"
19#include "sync/internal_api/public/base/model_type.h"
20#include "sync/protocol/sync_protocol_error.h"
21#include "sync/test/fake_server/fake_server.h"
22#include "sync/test/local_sync_test_server.h"
23
24
25class CommandLine;
26class Profile;
27class ProfileSyncServiceHarness;
28
29namespace net {
30class FakeURLFetcherFactory;
31class ProxyConfig;
32class ScopedDefaultHostResolverProc;
33class URLFetcherImplFactory;
34class URLRequestContextGetter;
35}
36
37// This is the base class for integration tests for all sync data types. Derived
38// classes must be defined for each sync data type. Individual tests are defined
39// using the IN_PROC_BROWSER_TEST_F macro.
40class SyncTest : public InProcessBrowserTest {
41 public:
42  // The different types of live sync tests that can be implemented.
43  enum TestType {
44    // Tests where only one client profile is synced with the server. Typically
45    // sanity level tests.
46    SINGLE_CLIENT,
47
48    // Tests where two client profiles are synced with the server. Typically
49    // functionality level tests.
50    TWO_CLIENT,
51
52    // Tests where three or more client profiles are synced with the server.
53    // Typically, these tests create client side races and verify that sync
54    // works.
55    MULTIPLE_CLIENT
56  };
57
58  // The type of server we're running against.
59  enum ServerType {
60    SERVER_TYPE_UNDECIDED,
61    LOCAL_PYTHON_SERVER,    // The mock python server that runs locally and is
62                            // part of the Chromium checkout.
63    LOCAL_LIVE_SERVER,      // Some other server (maybe the real binary used by
64                            // Google's sync service) that can be started on
65                            // a per-test basis by running a command
66    EXTERNAL_LIVE_SERVER,   // A remote server that the test code has no control
67                            // over whatsoever; cross your fingers that the
68                            // account state is initially clean.
69    IN_PROCESS_FAKE_SERVER, // The fake Sync server (FakeServer) running
70                            // in-process (bypassing HTTP calls). This
71                            // ServerType will eventually replace
72                            // LOCAL_PYTHON_SERVER.
73  };
74
75  // NOTE: IMPORTANT the enum here should match with
76  // the enum defined on the chromiumsync.py test server impl.
77  enum SyncErrorFrequency {
78    // Uninitialized state.
79    ERROR_FREQUENCY_NONE,
80
81    // Server sends the error on all requests.
82    ERROR_FREQUENCY_ALWAYS,
83
84    // Server sends the error on two thirds of the request.
85    // Note this is not random. The server would send the
86    // error on the first 2 requests of every 3 requests.
87    ERROR_FREQUENCY_TWO_THIRDS
88  };
89
90  // Authentication state used by the python sync server.
91  enum PythonServerAuthState {
92    // Python server processes sync requests normally.
93    AUTHENTICATED_TRUE,
94
95    // Python server responds to sync requests with an authentication error.
96    AUTHENTICATED_FALSE
97  };
98
99  // A SyncTest must be associated with a particular test type.
100  explicit SyncTest(TestType test_type);
101
102  virtual ~SyncTest();
103
104  // Validates command line parameters and creates a local python test server if
105  // specified.
106  virtual void SetUp() OVERRIDE;
107
108  // Brings down local python test server if one was created.
109  virtual void TearDown() OVERRIDE;
110
111  // Sets up command line flags required for sync tests.
112  virtual void SetUpCommandLine(CommandLine* cl) OVERRIDE;
113
114  // Used to get the number of sync clients used by a test.
115  int num_clients() WARN_UNUSED_RESULT { return num_clients_; }
116
117  // Returns a pointer to a particular sync profile. Callee owns the object
118  // and manages its lifetime.
119  Profile* GetProfile(int index) WARN_UNUSED_RESULT;
120
121  // Returns a pointer to a particular browser. Callee owns the object
122  // and manages its lifetime.
123  Browser* GetBrowser(int index) WARN_UNUSED_RESULT;
124
125  // Returns a pointer to a particular sync client. Callee owns the object
126  // and manages its lifetime.
127  ProfileSyncServiceHarness* GetClient(int index) WARN_UNUSED_RESULT;
128
129  // Returns a reference to the collection of sync clients. Callee owns the
130  // object and manages its lifetime.
131  std::vector<ProfileSyncServiceHarness*>& clients() WARN_UNUSED_RESULT {
132    return clients_.get();
133  }
134
135  // Returns a pointer to the sync profile that is used to verify changes to
136  // individual sync profiles. Callee owns the object and manages its lifetime.
137  Profile* verifier() WARN_UNUSED_RESULT;
138
139  // Used to determine whether the verifier profile should be updated or not.
140  bool use_verifier() WARN_UNUSED_RESULT { return use_verifier_; }
141
142  // After calling this method, changes made to a profile will no longer be
143  // reflected in the verifier profile. Note: Not all datatypes use this.
144  // TODO(rsimha): Hook up all datatypes to this mechanism.
145  void DisableVerifier();
146
147  // Initializes sync clients and profiles but does not sync any of them.
148  virtual bool SetupClients() WARN_UNUSED_RESULT;
149
150  // Initializes sync clients and profiles if required and syncs each of them.
151  virtual bool SetupSync() WARN_UNUSED_RESULT;
152
153  // Enable outgoing network connections for the given profile.
154  virtual void EnableNetwork(Profile* profile);
155
156  // Disable outgoing network connections for the given profile.
157  virtual void DisableNetwork(Profile* profile);
158
159  // Kicks off encryption for profile |index|.
160  bool EnableEncryption(int index);
161
162  // Checks if encryption is complete for profile |index|.
163  bool IsEncryptionComplete(int index);
164
165  // Blocks until all sync clients have completed their mutual sync cycles.
166  // Returns true if a quiescent state was successfully reached.
167  bool AwaitQuiescence();
168
169  // Returns true if the server being used supports controlling
170  // notifications.
171  bool ServerSupportsNotificationControl() const;
172
173  // Disable notifications on the server.  This operation is available
174  // only if ServerSupportsNotificationControl() returned true.
175  void DisableNotifications();
176
177  // Enable notifications on the server.  This operation is available
178  // only if ServerSupportsNotificationControl() returned true.
179  void EnableNotifications();
180
181  // Sets the mock gaia response for when an OAuth2 token is requested.
182  // Each call to this method will overwrite responses that were previously set.
183  void SetOAuth2TokenResponse(const std::string& response_data,
184                              net::HttpStatusCode response_code,
185                              net::URLRequestStatus::Status status);
186
187  // Trigger a notification to be sent to all clients.  This operation
188  // is available only if ServerSupportsNotificationControl() returned
189  // true.
190  void TriggerNotification(syncer::ModelTypeSet changed_types);
191
192  // Returns true if the server being used supports injecting errors.
193  bool ServerSupportsErrorTriggering() const;
194
195  // Triggers a migration for one or more datatypes, and waits
196  // for the server to complete it.  This operation is available
197  // only if ServerSupportsErrorTriggering() returned true.
198  void TriggerMigrationDoneError(syncer::ModelTypeSet model_types);
199
200  // Triggers the server to set its birthday to a random value thereby
201  // the server would return a birthday error on next sync.
202  void TriggerBirthdayError();
203
204  // Triggers a transient error on the server. Note the server will stay in
205  // this state until shut down.
206  void TriggerTransientError();
207
208  // Sets / unsets an auth error on the server. Can be used to simulate the case
209  // when the user's gaia password is changed at another location, or their
210  // OAuth2 tokens have expired. The server will stay in this state until
211  // this method is called with a different value.
212  void TriggerAuthState(PythonServerAuthState auth_state);
213
214  // Triggers an XMPP auth error on the server.  Note the server will
215  // stay in this state until shut down.
216  void TriggerXmppAuthError();
217
218  // Triggers a sync error on the server.
219  //   error: The error the server is expected to return.
220  //   frequency: Frequency with which the error is returned.
221  void TriggerSyncError(const syncer::SyncProtocolError& error,
222                        SyncErrorFrequency frequency);
223
224  // Triggers the creation the Synced Bookmarks folder on the server.
225  void TriggerCreateSyncedBookmarks();
226
227  // Returns the number of default items that every client syncs.
228  int NumberOfDefaultSyncItems() const;
229
230 protected:
231  // Add custom switches needed for running the test.
232  virtual void AddTestSwitches(CommandLine* cl);
233
234  // Append the command line switches to enable experimental types that aren't
235  // on by default yet.
236  virtual void AddOptionalTypesToCommandLine(CommandLine* cl);
237
238  // InProcessBrowserTest override. Destroys all the sync clients and sync
239  // profiles created by a test.
240  virtual void CleanUpOnMainThread() OVERRIDE;
241
242  // InProcessBrowserTest override. Changes behavior of the default host
243  // resolver to avoid DNS lookup errors.
244  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE;
245
246  // InProcessBrowserTest override. Resets the host resolver its default
247  // behavior.
248  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;
249
250  // Creates Profile, Browser and ProfileSyncServiceHarness instances for
251  // |index|. Used by SetupClients().
252  virtual void InitializeInstance(int index);
253
254  // Implementations of the EnableNotifications() and DisableNotifications()
255  // functions defined above.
256  void DisableNotificationsImpl();
257  void EnableNotificationsImpl();
258
259  // Set up the test to use the in-process fake server. This must be called
260  // before SetUp().
261  // TODO(pvalenzuela): Remove this method when the C++ fake server becomes
262  // the default server type.
263  void UseFakeServer();
264
265  // GAIA account used by the test case.
266  std::string username_;
267
268  // GAIA password used by the test case.
269  std::string password_;
270
271  // Locally available plain text file in which GAIA credentials are stored.
272  base::FilePath password_file_;
273
274  // The FakeServer used in tests with server type IN_PROCESS_FAKE_SERVER.
275  scoped_ptr<syncer::FakeServer> fake_server_;
276
277 private:
278  // Helper to ProfileManager::CreateProfile that handles path creation.
279  static Profile* MakeProfile(const base::FilePath::StringType name);
280
281  // Helper method used to read GAIA credentials from a local password file
282  // specified via the "--password-file-for-test" command line switch.
283  // Note: The password file must be a plain text file with exactly two lines --
284  // the username on the first line and the password on the second line.
285  void ReadPasswordFile();
286
287  // Helper method that starts up a sync test server if required.
288  void SetUpTestServerIfRequired();
289
290  // Helper method used to start up a local python test server. Note: We set up
291  // an XMPP-only python server if |server_type_| is LOCAL_LIVE_SERVER and mock
292  // gaia credentials are in use. Returns true if successful.
293  bool SetUpLocalPythonTestServer();
294
295  // Helper method used to start up a local sync test server. Returns true if
296  // successful.
297  bool SetUpLocalTestServer();
298
299  // Helper method used to destroy the local python sync test server if one was
300  // created. Returns true if successful.
301  bool TearDownLocalPythonTestServer();
302
303  // Helper method used to destroy the local sync test server if one was
304  // created. Returns true if successful.
305  bool TearDownLocalTestServer();
306
307  // Helper method that waits for up to |wait| for the test server
308  // to start. Splits the time into |intervals| intervals, and polls the
309  // server after each interval to see if it has started. Returns true if
310  // successful.
311  bool WaitForTestServerToStart(base::TimeDelta wait, int intervals);
312
313  // Helper method used to check if the test server is up and running.
314  bool IsTestServerRunning();
315
316  // Used to disable and enable network connectivity by providing and
317  // clearing an invalid proxy configuration.
318  void SetProxyConfig(net::URLRequestContextGetter* context,
319                      const net::ProxyConfig& proxy_config);
320
321  // Helper method used to set up fake responses for kClientLoginUrl,
322  // kIssueAuthTokenUrl, kGetUserInfoUrl and kSearchDomainCheckUrl in order to
323  // mock out calls to GAIA servers.
324  void SetupMockGaiaResponses();
325
326  // Helper method used to clear any fake responses that might have been set for
327  // various gaia URLs, cancel any outstanding URL requests, and return to using
328  // the default URLFetcher creation mechanism.
329  void ClearMockGaiaResponses();
330
331  // Python sync test server, started on demand.
332  syncer::LocalSyncTestServer sync_server_;
333
334  // Helper class to whitelist the notification port.
335  scoped_ptr<net::ScopedPortException> xmpp_port_;
336
337  // Used to differentiate between single-client, two-client, multi-client and
338  // many-client tests.
339  TestType test_type_;
340
341  // Tells us what kind of server we're using (some tests run only on certain
342  // server types).
343  ServerType server_type_;
344
345  // Number of sync clients that will be created by a test.
346  int num_clients_;
347
348  // Collection of sync profiles used by a test. A sync profile maintains sync
349  // data contained within its own subdirectory under the chrome user data
350  // directory. Profiles are owned by the ProfileManager.
351  std::vector<Profile*> profiles_;
352
353  // Collection of pointers to the browser objects used by a test. One browser
354  // instance is created for each sync profile. Browser object lifetime is
355  // managed by BrowserList, so we don't use a ScopedVector here.
356  std::vector<Browser*> browsers_;
357
358  // Collection of sync clients used by a test. A sync client is associated with
359  // a sync profile, and implements methods that sync the contents of the
360  // profile with the server.
361  ScopedVector<ProfileSyncServiceHarness> clients_;
362
363  // Sync profile against which changes to individual profiles are verified. We
364  // don't need a corresponding verifier sync client because the contents of the
365  // verifier profile are strictly local, and are not meant to be synced.
366  Profile* verifier_;
367
368  // Indicates whether changes to a profile should also change the verifier
369  // profile or not.
370  bool use_verifier_;
371
372  // Indicates whether or not notifications were explicitly enabled/disabled.
373  // Defaults to true.
374  bool notifications_enabled_;
375
376  // Sync integration tests need to make live DNS requests for access to
377  // GAIA and sync server URLs under google.com. We use a scoped version
378  // to override the default resolver while the test is active.
379  scoped_ptr<net::ScopedDefaultHostResolverProc> mock_host_resolver_override_;
380
381  // Used to start and stop the local test server.
382  base::ProcessHandle test_server_handle_;
383
384  // Fake URLFetcher factory used to mock out GAIA signin.
385  scoped_ptr<net::FakeURLFetcherFactory> fake_factory_;
386
387  // The URLFetcherImplFactory instance used to instantiate |fake_factory_|.
388  scoped_ptr<net::URLFetcherImplFactory> factory_;
389
390  // Number of default entries (as determined by the existing entries at setup
391  // time on client 0).
392  size_t number_of_default_sync_items_;
393
394  DISALLOW_COPY_AND_ASSIGN(SyncTest);
395};
396
397#endif  // CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_
398