blob: 034d6cafa22b93cfb93d79f7ccf95e2939d5893a [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/crosapi/browser_loader.h"
#include "base/auto_reset.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/component_updater/fake_cros_component_manager.h"
#include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
#include "chromeos/ash/components/dbus/upstart/fake_upstart_client.h"
#include "components/component_updater/mock_component_updater_service.h"
#include "components/update_client/update_client.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::Return;
namespace crosapi {
namespace {
// Copied from browser_loader.cc
constexpr char kLacrosComponentName[] = "lacros-dogfood-dev";
constexpr char kLacrosComponentId[] = "ldobopbhiamakmncndpkeelenhdmgfhk";
constexpr char kLacrosMounterUpstartJob[] = "lacros_2dmounter";
constexpr char kLacrosUnmounterUpstartJob[] = "lacros_2dunmounter";
} // namespace
class BrowserLoaderTest : public testing::Test {
public:
BrowserLoaderTest() {
// Create dependencies for object under test.
component_manager_ =
base::MakeRefCounted<component_updater::FakeCrOSComponentManager>();
component_manager_->set_supported_components({kLacrosComponentName});
component_manager_->ResetComponentState(
kLacrosComponentName,
component_updater::FakeCrOSComponentManager::ComponentInfo(
component_updater::CrOSComponentManager::Error::NONE,
base::FilePath("/install/path"), base::FilePath("/mount/path")));
browser_part_ = std::make_unique<BrowserProcessPlatformPartTestApi>(
g_browser_process->platform_part());
browser_part_->InitializeCrosComponentManager(component_manager_);
browser_loader_ = std::make_unique<BrowserLoader>(
component_manager_, &mock_component_update_service_,
&fake_upstart_client_);
}
~BrowserLoaderTest() override {
browser_part_->ShutdownCrosComponentManager();
}
// Public because this is test code.
content::BrowserTaskEnvironment task_environment_;
protected:
component_updater::MockComponentUpdateService mock_component_update_service_;
scoped_refptr<component_updater::FakeCrOSComponentManager> component_manager_;
ash::FakeUpstartClient fake_upstart_client_;
std::unique_ptr<BrowserProcessPlatformPartTestApi> browser_part_;
std::unique_ptr<BrowserLoader> browser_loader_;
private:
base::AutoReset<bool> set_lacros_enabled_ =
browser_util::SetLacrosEnabledForTest(true);
};
TEST_F(BrowserLoaderTest, OnLoadSelectionQuicklyChooseRootfs) {
bool callback_called = false;
fake_upstart_client_.set_start_job_cb(base::BindRepeating(
[](bool* b, const std::string& job,
const std::vector<std::string>& upstart_env) {
EXPECT_EQ(job, kLacrosMounterUpstartJob);
*b = true;
return true;
},
&callback_called));
// Set `was_installed` to false, in order to quickly mount rootfs
// lacros-chrome.
browser_loader_->OnLoadSelection(
base::BindOnce([](const base::FilePath&, LacrosSelection selection,
base::Version version) {
EXPECT_EQ(LacrosSelection::kRootfs, selection);
}),
false);
task_environment_.RunUntilIdle();
EXPECT_TRUE(callback_called);
}
TEST_F(BrowserLoaderTest, OnLoadVersionSelectionNeitherIsAvailable) {
// Use stateful when a rootfs lacros-chrome version is invalid.
bool callback_called = false;
fake_upstart_client_.set_start_job_cb(base::BindRepeating(
[](bool* b, const std::string& job,
const std::vector<std::string>& upstart_env) {
EXPECT_EQ(job, kLacrosUnmounterUpstartJob);
*b = true;
return true;
},
&callback_called));
// Pass in an invalid `base::Version`.
browser_loader_->OnLoadVersionSelection(
/*is_stateful_lacros_available=*/false,
base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
base::Version version) { EXPECT_TRUE(path.empty()); }),
/*rootfs_lacros_version=*/base::Version());
task_environment_.RunUntilIdle();
EXPECT_FALSE(callback_called);
}
TEST_F(BrowserLoaderTest, OnLoadVersionSelectionStatefulIsUnavailable) {
// Use rootfs when a stateful lacros-chrome version is invalid.
bool callback_called = false;
fake_upstart_client_.set_start_job_cb(base::BindRepeating(
[](bool* b, const std::string& job,
const std::vector<std::string>& upstart_env) {
EXPECT_EQ(job, kLacrosMounterUpstartJob);
*b = true;
return true;
},
&callback_called));
// Pass in an invalid `base::Version`.
browser_loader_->OnLoadVersionSelection(
/*is_stateful_lacros_available=*/false,
base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
base::Version version) {
EXPECT_EQ(LacrosSelection::kRootfs, selection);
}),
/*rootfs_lacros_version=*/base::Version("2.0.0"));
task_environment_.RunUntilIdle();
EXPECT_TRUE(callback_called);
}
TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsUnavailable) {
std::u16string lacros_component_name =
base::UTF8ToUTF16(base::StringPiece(kLacrosComponentName));
EXPECT_CALL(mock_component_update_service_, GetComponents())
.WillOnce(Return(std::vector<component_updater::ComponentInfo>{
{kLacrosComponentId, "", lacros_component_name,
base::Version("1.0.0")}}));
// Use stateful when a rootfs lacros-chrome version is invalid.
bool callback_called = false;
fake_upstart_client_.set_start_job_cb(base::BindRepeating(
[](bool* b, const std::string& job,
const std::vector<std::string>& upstart_env) {
EXPECT_EQ(job, kLacrosUnmounterUpstartJob);
*b = true;
return true;
},
&callback_called));
// Pass in an invalid `base::Version`.
browser_loader_->OnLoadVersionSelection(
/*is_stateful_lacros_available=*/true,
base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
base::Version version) {
EXPECT_EQ(LacrosSelection::kStateful, selection);
}),
/*rootfs_lacros_version=*/base::Version());
task_environment_.RunUntilIdle();
EXPECT_TRUE(callback_called);
}
TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsNewer) {
std::u16string lacros_component_name =
base::UTF8ToUTF16(base::StringPiece(kLacrosComponentName));
EXPECT_CALL(mock_component_update_service_, GetComponents())
.WillOnce(Return(std::vector<component_updater::ComponentInfo>{
{kLacrosComponentId, "", lacros_component_name,
base::Version("1.0.0")}}));
bool callback_called = false;
fake_upstart_client_.set_start_job_cb(base::BindRepeating(
[](bool* b, const std::string& job,
const std::vector<std::string>& upstart_env) {
EXPECT_EQ(job, kLacrosMounterUpstartJob);
*b = true;
return true;
},
&callback_called));
// Pass in a rootfs lacros-chrome version that is newer.
browser_loader_->OnLoadVersionSelection(
/*is_stateful_lacros_available=*/true,
base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
base::Version version) {
EXPECT_EQ(LacrosSelection::kRootfs, selection);
}),
/*rootfs_lacros_version=*/base::Version("2.0.0"));
task_environment_.RunUntilIdle();
EXPECT_TRUE(callback_called);
}
TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsOlder) {
// Use stateful when a rootfs lacros-chrome version is older.
std::u16string lacros_component_name =
base::UTF8ToUTF16(base::StringPiece(kLacrosComponentName));
EXPECT_CALL(mock_component_update_service_, GetComponents())
.WillOnce(Return(std::vector<component_updater::ComponentInfo>{
{kLacrosComponentId, "", lacros_component_name,
base::Version("3.0.0")}}));
bool callback_called = false;
fake_upstart_client_.set_start_job_cb(base::BindRepeating(
[](bool* b, const std::string& job,
const std::vector<std::string>& upstart_env) {
EXPECT_EQ(job, kLacrosUnmounterUpstartJob);
*b = true;
return true;
},
&callback_called));
// Pass in a rootfs lacros-chrome version that is older.
browser_loader_->OnLoadVersionSelection(
/*is_stateful_lacros_available=*/true,
base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
base::Version version) {
EXPECT_EQ(LacrosSelection::kStateful, selection);
}),
/*rootfs_lacros_version=*/base::Version("2.0.0"));
task_environment_.RunUntilIdle();
EXPECT_TRUE(callback_called);
}
} // namespace crosapi