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