blob: 4d59f59622221477ece9e5d1b40bc102bab120fd [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_
#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/test/integration/configuration_refresher.h"
#include "chrome/browser/sync/test/integration/fake_server_invalidation_sender.h"
#include "chrome/common/buildflags.h"
#include "components/gcm_driver/instance_id/instance_id.h"
#include "components/gcm_driver/instance_id/instance_id_driver.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/user_selectable_type.h"
#include "components/sync/test/fake_server/fake_server.h"
#include "net/base/net_errors.h"
#include "net/http/http_status_code.h"
#include "services/network/test/test_url_loader_factory.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/ui/app_list/app_list_syncable_service.h"
#endif // defined(OS_CHROMEOS)
#if defined(OS_ANDROID)
#include "chrome/test/base/android/android_browser_test.h"
#else
#include "chrome/browser/extensions/install_verifier.h"
#include "chrome/test/base/in_process_browser_test.h"
#endif
// The E2E tests are designed to run against real backend servers. To identify
// those tests we use *E2ETest* test name filter and run disabled tests.
//
// The following macros define how a test is run:
// - E2E_ONLY: Marks a test to run only as an E2E test against backend servers.
// These tests DO NOT run on regular Chromium waterfalls.
// - E2E_ENABLED: Marks a test to run as an E2E test in addition to Chromium
// waterfalls.
//
// To disable a test from running on Chromium waterfalls, you would still use
// the default DISABLED_test_name macro. To disable it from running as an E2E
// test outside Chromium waterfalls you would need to remove the E2E* macro.
#define MACRO_CONCAT(prefix, test_name) prefix##_##test_name
#define E2E_ONLY(test_name) MACRO_CONCAT(DISABLED_E2ETest, test_name)
#define E2E_ENABLED(test_name) MACRO_CONCAT(test_name, E2ETest)
class ProfileSyncServiceHarness;
namespace arc {
class SyncArcPackageHelper;
} // namespace arc
namespace base {
class CommandLine;
class ScopedTempDir;
} // namespace base
namespace fake_server {
class FakeServer;
} // namespace fake_server
namespace syncer {
class ProfileSyncService;
} // namespace syncer
// This is the base class for integration tests for all sync data types. Derived
// classes must be defined for each sync data type. Individual tests are defined
// using the IN_PROC_BROWSER_TEST_F macro.
class SyncTest : public PlatformBrowserTest {
public:
// The different types of live sync tests that can be implemented.
enum TestType {
// Tests where only one client profile is synced with the server. Typically
// sanity level tests.
SINGLE_CLIENT,
// Tests where two client profiles are synced with the server. Typically
// functionality level tests.
TWO_CLIENT,
};
// The type of server we're running against.
enum ServerType {
SERVER_TYPE_UNDECIDED,
EXTERNAL_LIVE_SERVER, // A remote server that the test code has no control
// over whatsoever; cross your fingers that the
// account state is initially clean.
IN_PROCESS_FAKE_SERVER, // The fake Sync server (FakeServer) running
// in-process (bypassing HTTP calls).
};
class FakeInstanceID : public instance_id::InstanceID {
public:
FakeInstanceID()
: instance_id::InstanceID("FakeAppId", /*gcm_driver = */ nullptr) {}
~FakeInstanceID() override = default;
void GetID(GetIDCallback callback) override {}
void GetCreationTime(GetCreationTimeCallback callback) override {}
void GetToken(const std::string& authorized_entity,
const std::string& scope,
base::TimeDelta time_to_live,
const std::map<std::string, std::string>& options,
std::set<Flags> flags,
GetTokenCallback callback) override;
void ValidateToken(const std::string& authorized_entity,
const std::string& scope,
const std::string& token,
ValidateTokenCallback callback) override {}
void DeleteToken(const std::string& authorized_entity,
const std::string& scope,
DeleteTokenCallback callback) override {}
protected:
void DeleteTokenImpl(const std::string& authorized_entity,
const std::string& scope,
DeleteTokenCallback callback) override {}
void DeleteIDImpl(DeleteIDCallback callback) override {}
private:
DISALLOW_COPY_AND_ASSIGN(FakeInstanceID);
};
class FakeInstanceIDDriver : public instance_id::InstanceIDDriver {
public:
FakeInstanceIDDriver()
: instance_id::InstanceIDDriver(/*gcm_driver=*/nullptr) {}
~FakeInstanceIDDriver() override = default;
instance_id::InstanceID* GetInstanceID(const std::string& app_id) override;
void RemoveInstanceID(const std::string& app_id) override {}
bool ExistsInstanceID(const std::string& app_id) const override;
private:
FakeInstanceID fake_instance_id_;
DISALLOW_COPY_AND_ASSIGN(FakeInstanceIDDriver);
};
// A SyncTest must be associated with a particular test type.
explicit SyncTest(TestType test_type);
~SyncTest() override;
void SetUp() override;
void TearDown() override;
void PostRunTestOnMainThread() override;
// Sets up command line flags required for sync tests.
void SetUpCommandLine(base::CommandLine* cl) override;
// Used to get the number of sync clients used by a test.
int num_clients() { return num_clients_; }
// Returns a pointer to a particular sync profile. Callee owns the object
// and manages its lifetime.
Profile* GetProfile(int index);
// Returns a list of all profiles including the verifier if available. Callee
// owns the objects and manages its lifetime.
std::vector<Profile*> GetAllProfiles();
#if !defined(OS_ANDROID)
// Returns a pointer to a particular browser. Callee owns the object
// and manages its lifetime.
Browser* GetBrowser(int index);
// Adds a new browser belonging to the profile at |profile_index|, and appends
// it to the list of browsers. Creates a copy of the Profile pointer in
// position |profile_index| and appends it to the list of profiles. This is
// done so that the profile associated with the new browser can be found at
// the same index as it. Tests typically use browser indexes and profile
// indexes interchangeably; this allows them to do so freely.
Browser* AddBrowser(int profile_index);
#endif
// Returns a pointer to a particular sync client. Callee owns the object
// and manages its lifetime.
ProfileSyncServiceHarness* GetClient(int index);
// Returns a list of the collection of sync clients.
std::vector<ProfileSyncServiceHarness*> GetSyncClients();
// Returns a ProfileSyncService at the given index.
syncer::ProfileSyncService* GetSyncService(int index);
// Returns the set of ProfileSyncServices.
std::vector<syncer::ProfileSyncService*> GetSyncServices();
// Returns the set of registered UserSelectableTypes. This is retrieved from
// the ProfileSyncService at the given |index|.
syncer::UserSelectableTypeSet GetRegisteredSelectableTypes(int index);
// Returns a pointer to the sync profile that is used to verify changes to
// individual sync profiles. Callee owns the object and manages its lifetime.
Profile* verifier();
// Used to determine whether the verifier profile should be updated or not.
bool use_verifier() { return use_verifier_; }
// After calling this method, changes made to a profile will no longer be
// reflected in the verifier profile. Note: Not all datatypes use this.
// TODO(rsimha): Hook up all datatypes to this mechanism.
void DisableVerifier();
// Initializes sync clients and profiles but does not sync any of them.
virtual bool SetupClients() WARN_UNUSED_RESULT;
// Initializes sync clients and profiles if required and syncs each of them.
virtual bool SetupSync() WARN_UNUSED_RESULT;
// This is similar to click the reset button on chrome.google.com/sync.
// Only takes effect when running with external servers.
// Please call this before setting anything. This method will clear all
// local profiles, browsers, etc.
void ResetSyncForPrimaryAccount();
// Like SetupSync() but does not wait for the clients to be ready to sync.
void SetupSyncNoWaitingForCompletion();
// Like SetupSync() but does wait for commits to complete before proceeding to
// another client.
// TODO(crbug.com/956043): Investigate deeper why such sequential setup is
// needed by some tests and why using SetupSync() instead is causing
// flakiness. Ideally get rid of this function.
void SetupSyncOneClientAfterAnother();
// Sets whether or not the sync clients in this test should respond to
// notifications of their own commits. Real sync clients do not do this, but
// many test assertions require this behavior.
//
// Default is to return true. Test should override this if they require
// different behavior.
virtual bool TestUsesSelfNotifications();
// Blocks until all sync clients have completed their mutual sync cycles.
// Returns true if a quiescent state was successfully reached.
bool AwaitQuiescence();
// Returns true if we are running tests against external servers.
bool UsingExternalServers();
// Sets the mock gaia response for when an OAuth2 token is requested.
// Each call to this method will overwrite responses that were previously set.
void SetOAuth2TokenResponse(const std::string& response_data,
net::HttpStatusCode response_code,
net::Error net_error);
// Triggers a migration for one or more datatypes, and waits
// for the server to complete it. This operation is available
// only if ServerSupportsErrorTriggering() returned true.
void TriggerMigrationDoneError(syncer::ModelTypeSet model_types);
// Returns the FakeServer being used for the test or null if FakeServer is
// not being used.
fake_server::FakeServer* GetFakeServer() const;
// Triggers a sync for the given |model_types| for the Profile at |index|.
void TriggerSyncForModelTypes(int index, syncer::ModelTypeSet model_types);
// The configuration refresher is triggering refreshes after the configuration
// phase is done (during start-up). Call this function before SetupSync() to
// avoid its effects.
void StopConfigurationRefresher();
arc::SyncArcPackageHelper* sync_arc_helper();
protected:
// Add custom switches needed for running the test.
void AddTestSwitches(base::CommandLine* cl);
// BrowserTestBase implementation:
void SetUpOnMainThread() override;
void TearDownOnMainThread() override;
void SetUpInProcessBrowserTestFixture() override;
void OnWillCreateBrowserContextServices(content::BrowserContext* context);
// Invoked immediately before creating profile |index| under |profile_path|.
virtual void BeforeSetupClient(int index, const base::FilePath& profile_path);
// Implementations of the EnableNotifications() and DisableNotifications()
// functions defined above.
void DisableNotificationsImpl();
void EnableNotificationsImpl();
// Helper to ProfileManager::CreateProfileAsync that creates a new profile
// used for UI Signin. Blocks until profile is created.
static Profile* MakeProfileForUISignin(base::FilePath profile_path);
// Stops notificatinos being sent to a client.
void DisableNotificationsForClient(int index);
// Sets a decryption passphrase to be used for a client. The passphrase will
// be provided to the client during initialization, before Sync starts. It is
// an error to provide both a decryption and encryption passphrases for one
// client.
void SetDecryptionPassphraseForClient(int index,
const std::string& passphrase);
// Sets an explicit encryption passphrase to be used for a client. The
// passphrase will be set for the client during initialization, before Sync
// starts. An encryption passphrase can be also enabled after initialization,
// but using this method ensures that Sync is never enabled when there is no
// passphrase, which allows tests to check for unencrypted data leaks. It is
// an error to provide both a decryption and encryption passphrases for one
// client.
void SetEncryptionPassphraseForClient(int index,
const std::string& passphrase);
// Sets up fake responses for kClientLoginUrl, kIssueAuthTokenUrl,
// kGetUserInfoUrl and kSearchDomainCheckUrl in order to mock out calls to
// GAIA servers.
void SetupMockGaiaResponsesForProfile(Profile* profile);
base::test::ScopedFeatureList feature_list_;
// The FakeServer used in tests with server type IN_PROCESS_FAKE_SERVER.
std::unique_ptr<fake_server::FakeServer> fake_server_;
// The factory used to mock out GAIA signin.
network::TestURLLoaderFactory test_url_loader_factory_;
private:
enum SetupSyncMode {
NO_WAITING,
WAIT_FOR_SYNC_SETUP_TO_COMPLETE,
WAIT_FOR_COMMITS_TO_COMPLETE
};
// Handles Profile creation for given index. Profile's path and type is
// determined at runtime based on server type.
bool CreateProfile(int index);
// Callback for MakeProfileForUISignin() method. It runs the quit_closure once
// profile is created successfully.
static void CreateProfileCallback(const base::Closure& quit_closure,
Profile* profile,
Profile::CreateStatus status);
static std::unique_ptr<KeyedService> CreateProfileInvalidationProvider(
std::map<const Profile*, syncer::FCMNetworkHandler*>*
profile_to_fcm_network_handler_map,
instance_id::InstanceIDDriver* instance_id_driver,
content::BrowserContext* context);
static std::unique_ptr<KeyedService> CreateSyncInvalidationsService(
instance_id::InstanceIDDriver* instance_id_driver,
content::BrowserContext* context);
// Helper to Profile::CreateProfile that handles path creation. It creates
// a profile then registers it as a testing profile.
Profile* MakeTestProfile(base::FilePath profile_path, int index);
// Helper to block the current thread while the data models sync depends on
// finish loading.
void WaitForDataModels(Profile* profile);
// Helper method used to read GAIA credentials from a local password file
// specified via the "--password-file-for-test" command line switch.
// Note: The password file must be a plain text file with exactly two lines --
// the username on the first line and the password on the second line.
void ReadPasswordFile();
// Helper method that starts up a sync test server if required.
void SetUpTestServerIfRequired();
// Helper method used to set up fake responses for kClientLoginUrl,
// kIssueAuthTokenUrl, kGetUserInfoUrl and kSearchDomainCheckUrl in order to
// mock out calls to GAIA servers.
void SetupMockGaiaResponses();
// Helper method used to clear any fake responses that might have been set for
// various gaia URLs, cancel any outstanding URL requests, and return to using
// the default URLFetcher creation mechanism.
void ClearMockGaiaResponses();
// Decide which sync server implementation to run against based on the type
// of test being run and command line args passed in.
void DecideServerType();
// Initializes any custom services needed for the |profile| at |index|.
void InitializeProfile(int index, Profile* profile);
// Sets up the client-side invalidations infrastructure depending on the
// value of |server_type_|.
void SetUpInvalidations(int index);
// Initializes the invalidations that were set up in SetUpInvalidations.
void InitializeInvalidations(int index);
// Internal routine for setting up sync.
void SetupSyncInternal(SetupSyncMode setup_mode);
void ClearProfiles();
// Used to differentiate between single-client and two-client tests.
const TestType test_type_;
// Used to remember when the test fixture was constructed and later understand
// how long the setup took.
const base::Time test_construction_time_;
// GAIA account used by the test case.
std::string username_;
// GAIA password used by the test case.
std::string password_;
// Locally available plain text file in which GAIA credentials are stored.
base::FilePath password_file_;
// Tells us what kind of server we're using (some tests run only on certain
// server types).
ServerType server_type_;
// The default profile, created before our actual testing |profiles_|. This is
// needed in a workaround for https://crbug.com/801569, see comments in the
// .cc file.
Profile* previous_profile_;
// Number of sync clients that will be created by a test.
int num_clients_;
// Collection of sync profiles used by a test. A sync profile maintains sync
// data contained within its own subdirectory under the chrome user data
// directory. Profiles are owned by the ProfileManager.
std::vector<Profile*> profiles_;
// Collection of profile delegates. Only used for test profiles, which
// require a custom profile delegate to ensure initialization happens at the
// right time.
std::vector<std::unique_ptr<Profile::Delegate>> profile_delegates_;
// List of temporary directories that need to be deleted when the test is
// completed, used for two-client tests with external server.
std::vector<std::unique_ptr<base::ScopedTempDir>> scoped_temp_dirs_;
#if !defined(OS_ANDROID)
// Collection of pointers to the browser objects used by a test. One browser
// instance is created for each sync profile. Browser object lifetime is
// managed by BrowserList, so we don't use a std::vector<std::unique_ptr<>>
// here.
std::vector<Browser*> browsers_;
#endif
// Collection of sync clients used by a test. A sync client is associated
// with a sync profile, and implements methods that sync the contents of the
// profile with the server.
std::vector<std::unique_ptr<ProfileSyncServiceHarness>> clients_;
// Mapping from client indexes to encryption passphrases to use for them.
std::map<int, std::string> client_encryption_passphrases_;
// Mapping from client indexes to decryption passphrases to use for them.
std::map<int, std::string> client_decryption_passphrases_;
// Owns the FakeServerInvalidationSender for each profile.
std::vector<std::unique_ptr<fake_server::FakeServerInvalidationSender>>
fake_server_invalidation_observers_;
// Maps a profile to the corresponding FCMNetworkHandler. Contains one entry
// per profile. It is used to simulate an incoming FCM messages to different
// profiles within the FakeServerInvalidationSender.
std::map<const Profile*, syncer::FCMNetworkHandler*>
profile_to_fcm_network_handler_map_;
FakeInstanceIDDriver fake_instance_id_driver_;
// Triggers a GetUpdates via refresh after a configuration.
std::unique_ptr<ConfigurationRefresher> configuration_refresher_;
std::unique_ptr<
BrowserContextDependencyManager::CreateServicesCallbackList::Subscription>
create_services_subscription_;
// Sync profile against which changes to individual profiles are verified.
// We don't need a corresponding verifier sync client because the contents
// of the verifier profile are strictly local, and are not meant to be
// synced.
Profile* verifier_;
// Indicates whether changes to a profile should also change the verifier
// profile or not.
bool use_verifier_;
// Indicates whether to use a new user data dir.
// Only used for external server tests with two clients.
bool use_new_user_data_dir_ = false;
#if !defined(OS_ANDROID)
// Disable extension install verification.
extensions::ScopedInstallVerifierBypassForTest ignore_install_verification_;
#endif
#if defined(OS_CHROMEOS)
// A factory-like callback to create a model updater for testing, which will
// take the place of the real updater in AppListSyncableService for testing.
std::unique_ptr<
app_list::AppListSyncableService::ScopedModelUpdaterFactoryForTest>
model_updater_factory_;
#endif
DISALLOW_COPY_AND_ASSIGN(SyncTest);
};
#endif // CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_TEST_H_