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