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