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