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