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