| // Copyright 2019 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/crostini/crostini_util.h" |
| |
| #include "base/functional/bind.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/run_loop.h" |
| #include "base/test/test_future.h" |
| #include "chrome/browser/ash/crostini/crostini_manager.h" |
| #include "chrome/browser/ash/crostini/crostini_pref_names.h" |
| #include "chrome/browser/ash/crostini/crostini_test_helper.h" |
| #include "chrome/browser/ash/guest_os/guest_os_pref_names.h" |
| #include "chrome/browser/component_updater/fake_cros_component_manager.h" |
| #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h" |
| #include "chrome/test/base/scoped_testing_local_state.h" |
| #include "chrome/test/base/testing_browser_process.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "chromeos/ash/components/dbus/chunneld/chunneld_client.h" |
| #include "chromeos/ash/components/dbus/cicerone/cicerone_client.h" |
| #include "chromeos/ash/components/dbus/concierge/concierge_client.h" |
| #include "chromeos/ash/components/dbus/concierge/fake_concierge_client.h" |
| #include "chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.h" |
| #include "chromeos/ash/components/dbus/dlcservice/dlcservice_client.h" |
| #include "chromeos/ash/components/dbus/seneschal/seneschal_client.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| constexpr char kDesktopFileId[] = "dummy1"; |
| constexpr int kDisplayId = 0; |
| |
| namespace crostini { |
| |
| class CrostiniUtilTest : public testing::Test { |
| public: |
| CrostiniUtilTest() |
| : app_id_(crostini::CrostiniTestHelper::GenerateAppId(kDesktopFileId)), |
| task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD), |
| local_state_(std::make_unique<ScopedTestingLocalState>( |
| TestingBrowserProcess::GetGlobal())), |
| browser_part_(g_browser_process->platform_part()) { |
| ash::ChunneldClient::InitializeFake(); |
| ash::CiceroneClient::InitializeFake(); |
| ash::ConciergeClient::InitializeFake(); |
| ash::DebugDaemonClient::InitializeFake(); |
| ash::SeneschalClient::InitializeFake(); |
| |
| fake_concierge_client_ = ash::FakeConciergeClient::Get(); |
| } |
| |
| ~CrostiniUtilTest() override { |
| ash::SeneschalClient::Shutdown(); |
| ash::DebugDaemonClient::Shutdown(); |
| ash::ConciergeClient::Shutdown(); |
| ash::CiceroneClient::Shutdown(); |
| ash::ChunneldClient::Shutdown(); |
| } |
| |
| CrostiniUtilTest(const CrostiniUtilTest&) = delete; |
| CrostiniUtilTest& operator=(const CrostiniUtilTest&) = delete; |
| |
| void SetUp() override { |
| ash::DlcserviceClient::InitializeFake(); |
| |
| component_manager_ = |
| base::MakeRefCounted<component_updater::FakeCrOSComponentManager>(); |
| component_manager_->set_supported_components({"cros-termina"}); |
| component_manager_->ResetComponentState( |
| "cros-termina", |
| component_updater::FakeCrOSComponentManager::ComponentInfo( |
| component_updater::CrOSComponentManager::Error::NONE, |
| base::FilePath("/install/path"), base::FilePath("/mount/path"))); |
| browser_part_.InitializeCrosComponentManager(component_manager_); |
| |
| profile_ = std::make_unique<TestingProfile>(); |
| test_helper_ = std::make_unique<CrostiniTestHelper>(profile_.get()); |
| test_helper_->SetupDummyApps(); |
| g_browser_process->platform_part() |
| ->InitializeSchedulerConfigurationManager(); |
| } |
| |
| void TearDown() override { |
| g_browser_process->platform_part()->ShutdownSchedulerConfigurationManager(); |
| test_helper_.reset(); |
| profile_.reset(); |
| browser_part_.ShutdownCrosComponentManager(); |
| component_manager_.reset(); |
| ash::DlcserviceClient::Shutdown(); |
| } |
| |
| protected: |
| raw_ptr<ash::FakeConciergeClient, DanglingUntriaged> fake_concierge_client_; |
| |
| std::unique_ptr<TestingProfile> profile_; |
| std::unique_ptr<CrostiniTestHelper> test_helper_; |
| std::string app_id_; |
| |
| private: |
| content::BrowserTaskEnvironment task_environment_; |
| std::unique_ptr<ScopedTestingLocalState> local_state_; |
| scoped_refptr<component_updater::FakeCrOSComponentManager> component_manager_; |
| BrowserProcessPlatformPartTestApi browser_part_; |
| }; |
| |
| TEST_F(CrostiniUtilTest, LaunchCallbackRunsOnRestartError) { |
| // Set Restart to fail. |
| fake_concierge_client_->set_start_vm_response({}); |
| |
| base::test::TestFuture<bool, const std::string&> result_future; |
| // Launch should fail and invoke callback. |
| LaunchCrostiniApp(profile_.get(), app_id_, kDisplayId, {}, |
| result_future.GetCallback()); |
| EXPECT_FALSE(result_future.Get<0>()); |
| EXPECT_EQ( |
| "crostini restart to launch app " |
| "pfdnkhehloenlegacemoalhjljmpllpc failed: 5", |
| result_future.Get<1>()); |
| } |
| |
| TEST_F(CrostiniUtilTest, ShouldStopVm) { |
| CrostiniManager* manager = CrostiniManager::GetForProfile(profile_.get()); |
| guest_os::GuestId containera(kCrostiniDefaultVmType, "apple", "banana"); |
| guest_os::GuestId containerb(kCrostiniDefaultVmType, "potato", "strawberry"); |
| base::Value::List containers; |
| containers.Append(containera.ToDictValue().Clone()); |
| containers.Append(containerb.ToDictValue().Clone()); |
| |
| manager->AddRunningVmForTesting("apple"); |
| manager->AddRunningVmForTesting("potato"); |
| manager->AddRunningContainerForTesting( |
| "apple", ContainerInfo("banana", "bo", "home", "1.2.3.4")); |
| manager->AddRunningContainerForTesting( |
| "potato", ContainerInfo("strawberry", "bo", "home", "1.2.3.4")); |
| |
| ASSERT_TRUE(manager->IsVmRunning("apple")); |
| ASSERT_TRUE(manager->IsVmRunning("potato")); |
| |
| profile_->GetPrefs()->SetList(guest_os::prefs::kGuestOsContainers, |
| std::move(containers)); |
| |
| EXPECT_TRUE(ShouldStopVm(profile_.get(), containera)); |
| } |
| |
| TEST_F(CrostiniUtilTest, ShouldNotStopVm) { |
| CrostiniManager* manager = CrostiniManager::GetForProfile(profile_.get()); |
| guest_os::GuestId containera(kCrostiniDefaultVmType, "apple", "banana"); |
| guest_os::GuestId containerb(kCrostiniDefaultVmType, "apple", "strawberry"); |
| base::Value::List containers; |
| containers.Append(containera.ToDictValue().Clone()); |
| containers.Append(containerb.ToDictValue().Clone()); |
| |
| manager->AddRunningVmForTesting("apple"); |
| manager->AddRunningContainerForTesting( |
| "apple", ContainerInfo("banana", "bo", "home", "1.2.3.4")); |
| manager->AddRunningContainerForTesting( |
| "apple", ContainerInfo("strawberry", "bo", "home", "1.2.3.4")); |
| |
| ASSERT_TRUE(manager->IsVmRunning("apple")); |
| |
| profile_->GetPrefs()->SetList(guest_os::prefs::kGuestOsContainers, |
| std::move(containers)); |
| |
| EXPECT_FALSE(ShouldStopVm(profile_.get(), containera)); |
| } |
| |
| } // namespace crostini |