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