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. 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. 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. 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