Commit d752ea96 authored by Kushagra Sinha's avatar Kushagra Sinha Committed by Commit Bot

Allow initializing crOS Account Manager in ephemeral mode

Some tests cannot create a proper task environment for running a real
instance of Chrome OS Account Manager.

Allow the creation and initialization of Chrome OS Account Manager in
ephemeral mode where it will not require a task environment for
initialization.

Bug: 1100833
Test: chromeos_components_unittests --gtest_filter="*AccountManager*Test*"
Change-Id: I181dbde347f91530ded431d4f8a505f9c6c30be8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2283305Reviewed-by: default avatarAnastasiia N <anastasiian@chromium.org>
Commit-Queue: Kush Sinha <sinhak@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790311}
parent f22d241c
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/files/important_file_writer.h" #include "base/files/important_file_writer.h"
...@@ -168,6 +169,16 @@ void AccountManager::SetPrefService(PrefService* pref_service) { ...@@ -168,6 +169,16 @@ void AccountManager::SetPrefService(PrefService* pref_service) {
pref_service_ = pref_service; pref_service_ = pref_service;
} }
void AccountManager::InitializeInEphemeralMode(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
Initialize(/* home_dir= */ base::FilePath(), url_loader_factory,
/* delay_network_call_runner= */
base::BindRepeating(
[](base::OnceClosure closure) { std::move(closure).Run(); }),
/* task_runner= */ nullptr, /* initialization_callback= */
base::DoNothing());
}
void AccountManager::Initialize( void AccountManager::Initialize(
const base::FilePath& home_dir, const base::FilePath& home_dir,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
...@@ -215,19 +226,28 @@ void AccountManager::Initialize( ...@@ -215,19 +226,28 @@ void AccountManager::Initialize(
task_runner_ = task_runner; task_runner_ = task_runner;
base::FilePath tokens_file_path; base::FilePath tokens_file_path;
if (!home_dir_.empty()) { if (!IsEphemeralMode()) {
DCHECK(task_runner_);
tokens_file_path = home_dir_.Append(kTokensFileName); tokens_file_path = home_dir_.Append(kTokensFileName);
writer_ = std::make_unique<base::ImportantFileWriter>(tokens_file_path, writer_ = std::make_unique<base::ImportantFileWriter>(tokens_file_path,
task_runner_); task_runner_);
} }
initialization_callbacks_.emplace_back(std::move(initialization_callback)); initialization_callbacks_.emplace_back(std::move(initialization_callback));
PostTaskAndReplyWithResult( if (!IsEphemeralMode()) {
task_runner_.get(), FROM_HERE, DCHECK(task_runner_);
base::BindOnce(&AccountManager::LoadAccountsFromDisk, tokens_file_path), PostTaskAndReplyWithResult(
base::BindOnce( task_runner_.get(), FROM_HERE,
&AccountManager::InsertAccountsAndRunInitializationCallbacks, base::BindOnce(&AccountManager::LoadAccountsFromDisk, tokens_file_path),
weak_factory_.GetWeakPtr(), initialization_start_time)); base::BindOnce(
&AccountManager::InsertAccountsAndRunInitializationCallbacks,
weak_factory_.GetWeakPtr(), initialization_start_time));
} else {
// We are running in ephemeral mode. There is nothing to load from disk.
RecordTokenLoadStatus(TokenLoadStatus::kSuccess);
InsertAccountsAndRunInitializationCallbacks(initialization_start_time,
/* accounts= */ AccountMap{});
}
} }
// static // static
...@@ -520,11 +540,12 @@ void AccountManager::UpsertAccountInternal(const AccountKey& account_key, ...@@ -520,11 +540,12 @@ void AccountManager::UpsertAccountInternal(const AccountKey& account_key,
} }
void AccountManager::PersistAccountsAsync() { void AccountManager::PersistAccountsAsync() {
if (!writer_) { if (IsEphemeralMode()) {
return; return;
} }
// Schedule (immediately) a non-blocking write. // Schedule (immediately) a non-blocking write.
DCHECK(writer_);
writer_->WriteNow(std::make_unique<std::string>(GetSerializedAccounts())); writer_->WriteNow(std::make_unique<std::string>(GetSerializedAccounts()));
} }
...@@ -656,6 +677,10 @@ void AccountManager::DeletePendingTokenRevocationRequest( ...@@ -656,6 +677,10 @@ void AccountManager::DeletePendingTokenRevocationRequest(
} }
} }
bool AccountManager::IsEphemeralMode() const {
return home_dir_.empty();
}
COMPONENT_EXPORT(ACCOUNT_MANAGER) COMPONENT_EXPORT(ACCOUNT_MANAGER)
std::ostream& operator<<(std::ostream& os, std::ostream& operator<<(std::ostream& os,
const AccountManager::AccountKey& account_key) { const AccountManager::AccountKey& account_key) {
......
...@@ -151,6 +151,12 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager { ...@@ -151,6 +151,12 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager {
DelayNetworkCallRunner delay_network_call_runner, DelayNetworkCallRunner delay_network_call_runner,
base::OnceClosure initialization_callback); base::OnceClosure initialization_callback);
// Initializes |AccountManager| for ephemeral / in-memory usage.
// Useful for tests that cannot afford to write to disk and clean up after
// themselves.
void InitializeInEphemeralMode(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
// Returns |true| if |AccountManager| has been fully initialized. // Returns |true| if |AccountManager| has been fully initialized.
bool IsInitialized() const; bool IsInitialized() const;
...@@ -356,6 +362,10 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager { ...@@ -356,6 +362,10 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager {
// Deletes |request| from |pending_token_revocation_requests_|, if present. // Deletes |request| from |pending_token_revocation_requests_|, if present.
void DeletePendingTokenRevocationRequest(GaiaTokenRevocationRequest* request); void DeletePendingTokenRevocationRequest(GaiaTokenRevocationRequest* request);
// Returns |true| if |AccountManager| is operating in ephemeral / in-memory
// mode, and not persisting anything to disk.
bool IsEphemeralMode() const;
// Status of this object's initialization. // Status of this object's initialization.
InitializationState init_state_ = InitializationState::kNotStarted; InitializationState init_state_ = InitializationState::kNotStarted;
...@@ -371,13 +381,16 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager { ...@@ -371,13 +381,16 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager {
PrefService* pref_service_ = nullptr; PrefService* pref_service_ = nullptr;
// A task runner for disk I/O. // A task runner for disk I/O.
// Will be |nullptr| if |AccountManager| is operating in ephemeral mode.
scoped_refptr<base::SequencedTaskRunner> task_runner_; scoped_refptr<base::SequencedTaskRunner> task_runner_;
// Writes |AccountManager|'s state to disk. Will be |nullptr| if // Writes |AccountManager|'s state to disk.
// |AccountManager| is operating in-memory only. // Will be |nullptr| if |AccountManager| is operating in ephemeral mode.
std::unique_ptr<base::ImportantFileWriter> writer_; std::unique_ptr<base::ImportantFileWriter> writer_;
// Cryptohome root. // Cryptohome root.
// Will be |base::FilePath::empty()| if |AccountManager| is operating in
// ephemeral mode.
base::FilePath home_dir_; base::FilePath home_dir_;
// A map from |AccountKey|s to |AccountInfo|. // A map from |AccountKey|s to |AccountInfo|.
......
...@@ -151,6 +151,15 @@ class AccountManagerTest : public testing::Test { ...@@ -151,6 +151,15 @@ class AccountManagerTest : public testing::Test {
std::move(initialization_callback)); std::move(initialization_callback));
} }
// |account_manager| is a non-owning pointer.
void InitializeEphemeralAccountManager(AccountManager* account_manager) {
account_manager->InitializeInEphemeralMode(
test_url_loader_factory_.GetSafeWeakWrapper());
account_manager->SetPrefService(&pref_service_);
RunAllPendingTasks();
EXPECT_TRUE(account_manager->IsInitialized());
}
void RunAllPendingTasks() { task_environment_.RunUntilIdle(); } void RunAllPendingTasks() { task_environment_.RunUntilIdle(); }
// Returns an unowned pointer to |AccountManager|. // Returns an unowned pointer to |AccountManager|.
...@@ -358,6 +367,24 @@ TEST_F(AccountManagerTest, TestTokenTransience) { ...@@ -358,6 +367,24 @@ TEST_F(AccountManagerTest, TestTokenTransience) {
EXPECT_EQ(0UL, accounts.size()); EXPECT_EQ(0UL, accounts.size());
} }
TEST_F(AccountManagerTest, TestEphemeralMode) {
{
// Create a scoped |AccountManager|.
AccountManager account_manager;
InitializeEphemeralAccountManager(&account_manager);
account_manager.UpsertAccount(kGaiaAccountKey, kRawUserEmail, kGaiaToken);
RunAllPendingTasks();
}
// Create another |AccountManager|.
AccountManager account_manager;
InitializeEphemeralAccountManager(&account_manager);
std::vector<AccountManager::Account> accounts =
GetAccountsBlocking(&account_manager);
EXPECT_EQ(0UL, accounts.size());
}
TEST_F(AccountManagerTest, TestAccountEmailPersistence) { TEST_F(AccountManagerTest, TestAccountEmailPersistence) {
account_manager()->UpsertAccount(kGaiaAccountKey, kRawUserEmail, kGaiaToken); account_manager()->UpsertAccount(kGaiaAccountKey, kRawUserEmail, kGaiaToken);
RunAllPendingTasks(); RunAllPendingTasks();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment