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