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