1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
|
// Copyright 2013 The Chromium Authors
// 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_SERVICE_IMPL_HARNESS_H_
#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_SERVICE_IMPL_HARNESS_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "chrome/browser/sync/test/integration/sync_test_account.h"
#include "components/sync/base/user_selectable_type.h"
#include "components/sync/engine/cycle/sync_cycle_snapshot.h"
#include "components/sync/service/local_data_description.h"
#include "components/sync/service/sync_service_impl.h"
#include "google_apis/gaia/gaia_id.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
class Profile;
namespace signin {
class GaiaIdHash;
} // namespace signin
namespace syncer {
class SyncSetupInProgressHandle;
class SyncUserSettings;
} // namespace syncer
class SyncSigninDelegate;
// An instance of this class is basically our notion of a "sync client" for
// automation purposes. It harnesses the SyncServiceImpl member of the
// profile passed to it on construction and automates certain things like setup
// and authentication. It provides ways to "wait" adequate periods of time for
// several clients to get to the same state.
class SyncServiceImplHarness {
public:
// The type of profile signin method to authenticate a profile.
enum class SigninType {
// Fakes user signin process.
FAKE_SIGNIN,
// Uses UI signin flow and connects to GAIA servers for authentication.
UI_SIGNIN
};
using SetUserSettingsCallback =
base::OnceCallback<void(syncer::SyncUserSettings*)>;
static std::unique_ptr<SyncServiceImplHarness> Create(
Profile* profile,
SigninType signin_type);
~SyncServiceImplHarness();
SyncServiceImplHarness(const SyncServiceImplHarness&) = delete;
SyncServiceImplHarness& operator=(const SyncServiceImplHarness&) = delete;
signin::GaiaIdHash GetGaiaIdHashForPrimaryAccount() const;
// Returns GaiaId for `account`. This method can be used when the account is
// not signed in.
GaiaId GetGaiaIdForAccount(SyncTestAccount account) const;
// Returns the email for `account`. This method can be used when the account
// is not signed in.
std::string GetEmailForAccount(SyncTestAccount account) const;
// Signs in to a primary account without enabling sync the feature.
[[nodiscard]] bool SignInPrimaryAccount(
SyncTestAccount account = SyncTestAccount::kDefaultAccount);
// This is similar to click the reset button on chrome.google.com/sync.
[[nodiscard]] bool ResetSyncForPrimaryAccount();
#if !BUILDFLAG(IS_CHROMEOS)
// Signs out of the primary account. ChromeOS doesn't have the concept of
// sign-out, so this only exists on other platforms.
void SignOutPrimaryAccount();
#endif // !BUILDFLAG(IS_CHROMEOS)
// The underlying implementation for mimic-ing persistent auth errors isn't
// implemented on Android, see https://crbug.com/1373448.
#if !BUILDFLAG(IS_ANDROID)
// Enters/exits the "Sync paused" state, which in real life happens if a
// syncing user signs out of the content area.
// TODO(crbug.com/401470426): Replace the usages with
// Enter/ExitSignInPendingStateForPrimaryAccount().
void EnterSyncPausedStateForPrimaryAccount();
bool ExitSyncPausedStateForPrimaryAccount();
// Enters the "Sign-in pending" state and waits until the sync transport
// layer is paused. Returns true if successful.
bool EnterSignInPendingStateForPrimaryAccount();
// Exits the "Sign-in pending" state and waits until the sync transport layer
// is active. Returns true if successful.
bool ExitSignInPendingStateForPrimaryAccount();
#endif // !BUILDFLAG(IS_ANDROID)
// Enables and configures sync for all available datatypes. Returns true only
// after sync has been fully initialized and authenticated, and we are ready
// to process changes.
[[nodiscard]] bool SetupSync(
SyncTestAccount account = SyncTestAccount::kDefaultAccount);
// Same as above but allows the modify sync settings (e.g. selected types) as
// part of the sync flow (advanced flow).
// `user_settings_callback` will be called once the engine is initialized, but
// before actually starting sync. Note that the caller is responsible for
// invoking `SetInitialSyncFeatureSetupComplete()`, if appropriate.
[[nodiscard]] bool SetupSyncWithCustomSettings(
SetUserSettingsCallback user_settings_callback,
SyncTestAccount account = SyncTestAccount::kDefaultAccount);
// Enables and configures sync.
// Does not wait for sync to be ready to process changes -- callers need to
// ensure this by calling AwaitSyncSetupCompletion() or
// AwaitSyncTransportActive().
[[nodiscard]] bool SetupSyncNoWaitForCompletion(
SyncTestAccount account = SyncTestAccount::kDefaultAccount);
// Same as above but allows the modify sync settings (e.g. selected types) as
// part of the sync flow (advanced flow).
// `user_settings_callback` will be called once the engine is initialized, but
// before actually starting sync. Note that the caller is responsible for
// invoking `SetInitialSyncFeatureSetupComplete()`, if appropriate.
[[nodiscard]] bool SetupSyncWithCustomSettingsNoWaitForCompletion(
SetUserSettingsCallback user_settings_callback,
SyncTestAccount account = SyncTestAccount::kDefaultAccount);
// Signals that sync setup is complete, and that PSS may begin syncing.
// Typically SetupSync does this automatically, but if that returned false,
// then setup may have been left incomplete.
void FinishSyncSetup();
// Calling this acts as a barrier and blocks the caller until `this` and
// `partner` have both completed a sync cycle. When calling this method,
// the `partner` should be the passive responder who responds to the actions
// of `this`. This method relies upon the synchronization of callbacks
// from the message queue. Returns true if two sync cycles have completed.
// Note: Use this method when exactly one client makes local change(s), and
// exactly one client is waiting to receive those changes.
[[nodiscard]] bool AwaitMutualSyncCycleCompletion(
SyncServiceImplHarness* partner);
// Blocks the caller until every client in `clients` completes its ongoing
// sync cycle and all the clients' progress markers match. Note: Use this
// method when more than one client makes local change(s), and more than one
// client is waiting to receive those changes.
[[nodiscard]] static bool AwaitQuiescence(
const std::vector<SyncServiceImplHarness*>& clients);
// Blocks the caller until the sync engine is initialized or some end state
// (e.g., auth error) is reached. Returns true only if the engine initialized
// successfully. See SyncService::IsEngineInitialized() for the definition
// of engine initialization.
[[nodiscard]] bool AwaitEngineInitialization();
// Blocks the caller until sync setup is complete, and sync-the-feature is
// active. Returns true if and only if sync setup completed successfully. Make
// sure to actually start sync setup (usually by calling SetupSync() or one of
// its variants) before.
[[nodiscard]] bool AwaitSyncSetupCompletion();
// Blocks the caller until the sync transport layer is active. Returns true if
// successful.
[[nodiscard]] bool AwaitSyncTransportActive();
// Blocks the caller until the sync transport layer is paused. Returns true if
// successful.
[[nodiscard]] bool AwaitSyncTransportPaused();
// Blocks the caller until invalidations are enabled or disabled.
[[nodiscard]] bool AwaitInvalidationsStatus(bool expected_status);
// Returns the SyncServiceImpl member of the sync client.
syncer::SyncServiceImpl* service() { return service_; }
const syncer::SyncServiceImpl* service() const { return service_; }
// Returns the debug name for this profile. Used for logging.
const std::string& profile_debug_name() const { return profile_debug_name_; }
// Enables sync for a particular selectable sync type (will enable sync for
// all corresponding datatypes). Returns true on success.
[[nodiscard]] bool EnableSyncForType(syncer::UserSelectableType type);
// Disables sync for a particular selectable sync type (will enable sync for
// all corresponding datatypes). Returns true on success.
[[nodiscard]] bool DisableSyncForType(syncer::UserSelectableType type);
// Enables sync for all registered sync datatypes. Returns true on success.
[[nodiscard]] bool EnableSyncForRegisteredDatatypes();
// Disables sync for all sync datatypes. Returns true on success.
[[nodiscard]] bool DisableSyncForAllDatatypes();
// Returns a snapshot of the current sync session.
syncer::SyncCycleSnapshot GetLastCycleSnapshot() const;
// Returns the datatypes which have local changes that have not yet been
// synced with the server.
absl::flat_hash_map<syncer::DataType, size_t> GetTypesWithUnsyncedDataAndWait(
syncer::DataTypeSet requested_types) const;
// Retrieves the LocalDataDescription for the specified `data_type`.
// it assumes the service will provide a unique description for this specific
// type. Returns this description, or default value (empty value) if the
// service misbehaves and returns a response that cannot be interpreted.
syncer::LocalDataDescription GetLocalDataDescriptionAndWait(
syncer::DataType data_type);
private:
// `profile` must not be null and must outlive `this`. `signin_delegate` must
// not be null.
SyncServiceImplHarness(Profile* profile,
std::unique_ptr<SyncSigninDelegate> signin_delegate);
// Gets detailed status from `service_` in pretty-printable form.
std::string GetServiceStatus();
// Returns a string with relevant info about client's sync state (if
// available), annotated with `message`. Useful for logging.
std::string GetClientInfoString(const std::string& message) const;
// Returns true if the user has enabled and configured sync for this client.
// Note that this does not imply sync is actually running.
bool IsSyncEnabledByUser() const;
// Profile associated with this sync client. WeakPtr is used to allow
// flexibility in tests: this object may outlive `Profile` as long as it isn't
// exercised.
const base::WeakPtr<Profile> profile_;
// SyncServiceImpl object associated with |profile_|.
const raw_ptr<syncer::SyncServiceImpl, AcrossTasksDanglingUntriaged> service_;
// Prevents Sync from running until configuration is complete.
std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_;
// Used for logging.
const std::string profile_debug_name_;
// Delegate to sign-in the test account across platforms.
const std::unique_ptr<SyncSigninDelegate> signin_delegate_;
};
#endif // CHROME_BROWSER_SYNC_TEST_INTEGRATION_SYNC_SERVICE_IMPL_HARNESS_H_
|