summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/test/integration/sync_test.h
blob: 6313c25902a13c0f4616d7a6fb0fd10563598ad6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_
#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request_status.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/protocol/sync_protocol_error.h"
#include "sync/test/fake_server/fake_server.h"
#include "sync/test/local_sync_test_server.h"


class CommandLine;
class Profile;
class ProfileSyncServiceHarness;

namespace net {
class FakeURLFetcherFactory;
class ProxyConfig;
class ScopedDefaultHostResolverProc;
class URLFetcherImplFactory;
class URLRequestContextGetter;
}

// This is the base class for integration tests for all sync data types. Derived
// classes must be defined for each sync data type. Individual tests are defined
// using the IN_PROC_BROWSER_TEST_F macro.
class SyncTest : public InProcessBrowserTest {
 public:
  // The different types of live sync tests that can be implemented.
  enum TestType {
    // Tests where only one client profile is synced with the server. Typically
    // sanity level tests.
    SINGLE_CLIENT,

    // Tests where two client profiles are synced with the server. Typically
    // functionality level tests.
    TWO_CLIENT,

    // Tests where three or more client profiles are synced with the server.
    // Typically, these tests create client side races and verify that sync
    // works.
    MULTIPLE_CLIENT
  };

  // The type of server we're running against.
  enum ServerType {
    SERVER_TYPE_UNDECIDED,
    LOCAL_PYTHON_SERVER,    // The mock python server that runs locally and is
                            // part of the Chromium checkout.
    LOCAL_LIVE_SERVER,      // Some other server (maybe the real binary used by
                            // Google's sync service) that can be started on
                            // a per-test basis by running a command
    EXTERNAL_LIVE_SERVER,   // A remote server that the test code has no control
                            // over whatsoever; cross your fingers that the
                            // account state is initially clean.
    IN_PROCESS_FAKE_SERVER, // The fake Sync server (FakeServer) running
                            // in-process (bypassing HTTP calls). This
                            // ServerType will eventually replace
                            // LOCAL_PYTHON_SERVER.
  };

  // This enum is used in conjunction with WithParamInterface to run tests with
  // and without the fake server.
  // TODO(pvalenzuela): Remove this when FakeServer is the default server.
  enum FakeServerExperiment {
    // The test should use the default logic for determining the test server.
    USE_DEFAULT_SERVER,

    // The test should use the fake server.
    USE_FAKE_SERVER,
  };

  // NOTE: IMPORTANT the enum here should match with
  // the enum defined on the chromiumsync.py test server impl.
  enum SyncErrorFrequency {
    // Uninitialized state.
    ERROR_FREQUENCY_NONE,

    // Server sends the error on all requests.
    ERROR_FREQUENCY_ALWAYS,

    // Server sends the error on two thirds of the request.
    // Note this is not random. The server would send the
    // error on the first 2 requests of every 3 requests.
    ERROR_FREQUENCY_TWO_THIRDS
  };

  // Authentication state used by the python sync server.
  enum PythonServerAuthState {
    // Python server processes sync requests normally.
    AUTHENTICATED_TRUE,

    // Python server responds to sync requests with an authentication error.
    AUTHENTICATED_FALSE
  };

  // A SyncTest must be associated with a particular test type.
  explicit SyncTest(TestType test_type);

  virtual ~SyncTest();

  // Validates command line parameters and creates a local python test server if
  // specified.
  virtual void SetUp() OVERRIDE;

  // Brings down local python test server if one was created.
  virtual void TearDown() OVERRIDE;

  // Sets up command line flags required for sync tests.
  virtual void SetUpCommandLine(CommandLine* cl) OVERRIDE;

  // Used to get the number of sync clients used by a test.
  int num_clients() WARN_UNUSED_RESULT { return num_clients_; }

  // Returns a pointer to a particular sync profile. Callee owns the object
  // and manages its lifetime.
  Profile* GetProfile(int index) WARN_UNUSED_RESULT;

  // Returns a pointer to a particular browser. Callee owns the object
  // and manages its lifetime.
  Browser* GetBrowser(int index) WARN_UNUSED_RESULT;

  // Returns a pointer to a particular sync client. Callee owns the object
  // and manages its lifetime.
  ProfileSyncServiceHarness* GetClient(int index) WARN_UNUSED_RESULT;

  // Returns a reference to the collection of sync clients. Callee owns the
  // object and manages its lifetime.
  std::vector<ProfileSyncServiceHarness*>& clients() WARN_UNUSED_RESULT {
    return clients_.get();
  }

  // Returns a pointer to the sync profile that is used to verify changes to
  // individual sync profiles. Callee owns the object and manages its lifetime.
  Profile* verifier() WARN_UNUSED_RESULT;

  // Used to determine whether the verifier profile should be updated or not.
  bool use_verifier() WARN_UNUSED_RESULT { return use_verifier_; }

  // After calling this method, changes made to a profile will no longer be
  // reflected in the verifier profile. Note: Not all datatypes use this.
  // TODO(rsimha): Hook up all datatypes to this mechanism.
  void DisableVerifier();

  // Initializes sync clients and profiles but does not sync any of them.
  virtual bool SetupClients() WARN_UNUSED_RESULT;

  // Initializes sync clients and profiles if required and syncs each of them.
  virtual bool SetupSync() WARN_UNUSED_RESULT;

  // Enable outgoing network connections for the given profile.
  virtual void EnableNetwork(Profile* profile);

  // Disable outgoing network connections for the given profile.
  virtual void DisableNetwork(Profile* profile);

  // Kicks off encryption for profile |index|.
  bool EnableEncryption(int index);

  // Checks if encryption is complete for profile |index|.
  bool IsEncryptionComplete(int index);

  // Blocks until all sync clients have completed their mutual sync cycles.
  // Returns true if a quiescent state was successfully reached.
  bool AwaitQuiescence();

  // Returns true if the server being used supports controlling
  // notifications.
  bool ServerSupportsNotificationControl() const;

  // Disable notifications on the server.  This operation is available
  // only if ServerSupportsNotificationControl() returned true.
  void DisableNotifications();

  // Enable notifications on the server.  This operation is available
  // only if ServerSupportsNotificationControl() returned true.
  void EnableNotifications();

  // Sets the mock gaia response for when an OAuth2 token is requested.
  // Each call to this method will overwrite responses that were previously set.
  void SetOAuth2TokenResponse(const std::string& response_data,
                              net::HttpStatusCode response_code,
                              net::URLRequestStatus::Status status);

  // Trigger a notification to be sent to all clients.  This operation
  // is available only if ServerSupportsNotificationControl() returned
  // true.
  void TriggerNotification(syncer::ModelTypeSet changed_types);

  // Returns true if the server being used supports injecting errors.
  bool ServerSupportsErrorTriggering() const;

  // Triggers a migration for one or more datatypes, and waits
  // for the server to complete it.  This operation is available
  // only if ServerSupportsErrorTriggering() returned true.
  void TriggerMigrationDoneError(syncer::ModelTypeSet model_types);

  // Triggers the server to set its birthday to a random value thereby
  // the server would return a birthday error on next sync.
  void TriggerBirthdayError();

  // Triggers a transient error on the server. Note the server will stay in
  // this state until shut down.
  void TriggerTransientError();

  // Sets / unsets an auth error on the server. Can be used to simulate the case
  // when the user's gaia password is changed at another location, or their
  // OAuth2 tokens have expired. The server will stay in this state until
  // this method is called with a different value.
  void TriggerAuthState(PythonServerAuthState auth_state);

  // Triggers an XMPP auth error on the server.  Note the server will
  // stay in this state until shut down.
  void TriggerXmppAuthError();

  // Triggers a sync error on the server.
  //   error: The error the server is expected to return.
  //   frequency: Frequency with which the error is returned.
  void TriggerSyncError(const syncer::SyncProtocolError& error,
                        SyncErrorFrequency frequency);

  // Triggers the creation the Synced Bookmarks folder on the server.
  void TriggerCreateSyncedBookmarks();

 protected:
  // Add custom switches needed for running the test.
  virtual void AddTestSwitches(CommandLine* cl);

  // Append the command line switches to enable experimental types that aren't
  // on by default yet.
  virtual void AddOptionalTypesToCommandLine(CommandLine* cl);

  // InProcessBrowserTest override. Destroys all the sync clients and sync
  // profiles created by a test.
  virtual void CleanUpOnMainThread() OVERRIDE;

  // InProcessBrowserTest override. Changes behavior of the default host
  // resolver to avoid DNS lookup errors.
  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE;

  // InProcessBrowserTest override. Resets the host resolver its default
  // behavior.
  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;

  // Creates Profile, Browser and ProfileSyncServiceHarness instances for
  // |index|. Used by SetupClients().
  virtual void InitializeInstance(int index);

  // Implementations of the EnableNotifications() and DisableNotifications()
  // functions defined above.
  void DisableNotificationsImpl();
  void EnableNotificationsImpl();

  // Set up the test to use the in-process fake server. This must be called
  // before SetUp().
  // TODO(pvalenzuela): Remove this method when the C++ fake server becomes
  // the default server type.
  void UseFakeServer();

  // GAIA account used by the test case.
  std::string username_;

  // GAIA password used by the test case.
  std::string password_;

  // Locally available plain text file in which GAIA credentials are stored.
  base::FilePath password_file_;

  // The FakeServer used in tests with server type IN_PROCESS_FAKE_SERVER.
  scoped_ptr<fake_server::FakeServer> fake_server_;

 private:
  // Helper to ProfileManager::CreateProfile that handles path creation.
  static Profile* MakeProfile(const base::FilePath::StringType name);

  // Helper method used to read GAIA credentials from a local password file
  // specified via the "--password-file-for-test" command line switch.
  // Note: The password file must be a plain text file with exactly two lines --
  // the username on the first line and the password on the second line.
  void ReadPasswordFile();

  // Helper method that starts up a sync test server if required.
  void SetUpTestServerIfRequired();

  // Helper method used to start up a local python test server. Note: We set up
  // an XMPP-only python server if |server_type_| is LOCAL_LIVE_SERVER and mock
  // gaia credentials are in use. Returns true if successful.
  bool SetUpLocalPythonTestServer();

  // Helper method used to start up a local sync test server. Returns true if
  // successful.
  bool SetUpLocalTestServer();

  // Helper method used to destroy the local python sync test server if one was
  // created. Returns true if successful.
  bool TearDownLocalPythonTestServer();

  // Helper method used to destroy the local sync test server if one was
  // created. Returns true if successful.
  bool TearDownLocalTestServer();

  // Helper method that waits for up to |wait| for the test server
  // to start. Splits the time into |intervals| intervals, and polls the
  // server after each interval to see if it has started. Returns true if
  // successful.
  bool WaitForTestServerToStart(base::TimeDelta wait, int intervals);

  // Helper method used to check if the test server is up and running.
  bool IsTestServerRunning();

  // Used to disable and enable network connectivity by providing and
  // clearing an invalid proxy configuration.
  void SetProxyConfig(net::URLRequestContextGetter* context,
                      const net::ProxyConfig& proxy_config);

  // Helper method used to set up fake responses for kClientLoginUrl,
  // kIssueAuthTokenUrl, kGetUserInfoUrl and kSearchDomainCheckUrl in order to
  // mock out calls to GAIA servers.
  void SetupMockGaiaResponses();

  // Helper method used to clear any fake responses that might have been set for
  // various gaia URLs, cancel any outstanding URL requests, and return to using
  // the default URLFetcher creation mechanism.
  void ClearMockGaiaResponses();

  // Python sync test server, started on demand.
  syncer::LocalSyncTestServer sync_server_;

  // Helper class to whitelist the notification port.
  scoped_ptr<net::ScopedPortException> xmpp_port_;

  // Used to differentiate between single-client, two-client, multi-client and
  // many-client tests.
  TestType test_type_;

  // Tells us what kind of server we're using (some tests run only on certain
  // server types).
  ServerType server_type_;

  // Number of sync clients that will be created by a test.
  int num_clients_;

  // Collection of sync profiles used by a test. A sync profile maintains sync
  // data contained within its own subdirectory under the chrome user data
  // directory. Profiles are owned by the ProfileManager.
  std::vector<Profile*> profiles_;

  // Collection of pointers to the browser objects used by a test. One browser
  // instance is created for each sync profile. Browser object lifetime is
  // managed by BrowserList, so we don't use a ScopedVector here.
  std::vector<Browser*> browsers_;

  // Collection of sync clients used by a test. A sync client is associated with
  // a sync profile, and implements methods that sync the contents of the
  // profile with the server.
  ScopedVector<ProfileSyncServiceHarness> clients_;

  // Sync profile against which changes to individual profiles are verified. We
  // don't need a corresponding verifier sync client because the contents of the
  // verifier profile are strictly local, and are not meant to be synced.
  Profile* verifier_;

  // Indicates whether changes to a profile should also change the verifier
  // profile or not.
  bool use_verifier_;

  // Indicates whether or not notifications were explicitly enabled/disabled.
  // Defaults to true.
  bool notifications_enabled_;

  // Sync integration tests need to make live DNS requests for access to
  // GAIA and sync server URLs under google.com. We use a scoped version
  // to override the default resolver while the test is active.
  scoped_ptr<net::ScopedDefaultHostResolverProc> mock_host_resolver_override_;

  // Used to start and stop the local test server.
  base::ProcessHandle test_server_handle_;

  // Fake URLFetcher factory used to mock out GAIA signin.
  scoped_ptr<net::FakeURLFetcherFactory> fake_factory_;

  // The URLFetcherImplFactory instance used to instantiate |fake_factory_|.
  scoped_ptr<net::URLFetcherImplFactory> factory_;

  DISALLOW_COPY_AND_ASSIGN(SyncTest);
};

#endif  // CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_