| // Copyright 2018 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. |
| |
| #include "chrome/browser/ash/guest_os/guest_os_registry_service.h" |
| |
| #include <stddef.h> |
| |
| #include "base/macros.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/simple_test_clock.h" |
| #include "chrome/browser/ash/crostini/crostini_pref_names.h" |
| #include "chrome/browser/ash/crostini/crostini_test_helper.h" |
| #include "chrome/browser/ash/crostini/crostini_util.h" |
| #include "chrome/browser/ash/crostini/fake_crostini_features.h" |
| #include "chrome/browser/ash/guest_os/guest_os_pref_names.h" |
| #include "chrome/browser/ash/plugin_vm/fake_plugin_vm_features.h" |
| #include "chrome/browser/ash/plugin_vm/plugin_vm_test_helper.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "chromeos/dbus/vm_applications/apps.pb.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::_; |
| using vm_tools::apps::App; |
| using vm_tools::apps::ApplicationList; |
| |
| constexpr char kCrostiniAppsInstalledHistogram[] = |
| "Crostini.AppsInstalledAtLogin"; |
| |
| constexpr char kPluginVmAppsInstalledHistogram[] = |
| "PluginVm.AppsInstalledAtLogin"; |
| |
| namespace guest_os { |
| |
| class GuestOsRegistryServiceTest : public testing::Test { |
| public: |
| GuestOsRegistryServiceTest() : crostini_test_helper_(&profile_) { |
| RecreateService(); |
| } |
| |
| protected: |
| void RecreateService() { |
| service_.reset(nullptr); |
| service_ = std::make_unique<GuestOsRegistryService>(&profile_); |
| service_->SetClockForTesting(&test_clock_); |
| } |
| |
| class Observer : public GuestOsRegistryService::Observer { |
| public: |
| MOCK_METHOD5(OnRegistryUpdated, |
| void(GuestOsRegistryService*, |
| GuestOsRegistryService::VmType, |
| const std::vector<std::string>&, |
| const std::vector<std::string>&, |
| const std::vector<std::string>&)); |
| }; |
| |
| guest_os::GuestOsRegistryService* service() { return service_.get(); } |
| TestingProfile* profile() { return &profile_; } |
| |
| std::vector<std::string> GetRegisteredAppIds() { |
| std::vector<std::string> result; |
| for (const auto& pair : service_->GetAllRegisteredApps()) { |
| result.emplace_back(pair.first); |
| } |
| return result; |
| } |
| |
| std::vector<std::string> GetEnabledAppIds() { |
| std::vector<std::string> result; |
| for (const auto& pair : service_->GetEnabledApps()) { |
| result.emplace_back(pair.first); |
| } |
| return result; |
| } |
| |
| protected: |
| base::SimpleTestClock test_clock_; |
| |
| private: |
| content::BrowserTaskEnvironment task_environment_; |
| TestingProfile profile_; |
| crostini::CrostiniTestHelper crostini_test_helper_; |
| |
| std::unique_ptr<GuestOsRegistryService> service_; |
| |
| DISALLOW_COPY_AND_ASSIGN(GuestOsRegistryServiceTest); |
| }; |
| |
| TEST_F(GuestOsRegistryServiceTest, SetAndGetRegistration) { |
| std::string desktop_file_id = "vim"; |
| auto vm_type = vm_tools::apps::ApplicationList::TERMINA; |
| std::string vm_name = "awesomevm"; |
| std::string container_name = "awesomecontainer"; |
| std::map<std::string, std::string> name = {{"", "Vim"}}; |
| std::map<std::string, std::string> comment = {{"", "Edit text files"}}; |
| std::map<std::string, std::set<std::string>> keywords = { |
| {"", {"very", "awesome"}}}; |
| std::set<std::string> mime_types = {"text/plain", "text/x-python"}; |
| bool no_display = true; |
| std::string exec = "execName --extra-arg=true"; |
| std::string executable_file_name = "execName"; |
| std::string package_id = |
| "vim;2:8.0.0197-4+deb9u1;amd64;installed:debian-stable"; |
| |
| std::string app_id = crostini::CrostiniTestHelper::GenerateAppId( |
| desktop_file_id, vm_name, container_name); |
| EXPECT_FALSE(service()->GetRegistration(app_id).has_value()); |
| |
| ApplicationList app_list; |
| app_list.set_vm_type(vm_type); |
| app_list.set_vm_name(vm_name); |
| app_list.set_container_name(container_name); |
| |
| App* app = app_list.add_apps(); |
| app->set_desktop_file_id(desktop_file_id); |
| app->set_no_display(no_display); |
| app->set_exec(exec); |
| app->set_executable_file_name(executable_file_name); |
| app->set_package_id(package_id); |
| |
| for (const auto& localized_name : name) { |
| App::LocaleString::Entry* entry = app->mutable_name()->add_values(); |
| entry->set_locale(localized_name.first); |
| entry->set_value(localized_name.second); |
| } |
| |
| for (const auto& localized_comment : comment) { |
| App::LocaleString::Entry* entry = app->mutable_comment()->add_values(); |
| entry->set_locale(localized_comment.first); |
| entry->set_value(localized_comment.second); |
| } |
| |
| for (const auto& localized_keywords : keywords) { |
| auto* keywords_with_locale = app->mutable_keywords()->add_values(); |
| keywords_with_locale->set_locale(localized_keywords.first); |
| for (const auto& localized_keyword : localized_keywords.second) { |
| keywords_with_locale->add_value(localized_keyword); |
| } |
| } |
| |
| for (const std::string& mime_type : mime_types) |
| app->add_mime_types(mime_type); |
| |
| service()->UpdateApplicationList(app_list); |
| absl::optional<GuestOsRegistryService::Registration> result = |
| service()->GetRegistration(app_id); |
| ASSERT_TRUE(result.has_value()); |
| EXPECT_EQ(result->DesktopFileId(), desktop_file_id); |
| EXPECT_EQ( |
| result->VmType(), |
| absl::make_optional( |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA)); |
| EXPECT_EQ(result->VmName(), vm_name); |
| EXPECT_EQ(result->ContainerName(), container_name); |
| EXPECT_EQ(result->Name(), name[""]); |
| EXPECT_EQ(result->Comment(), comment[""]); |
| EXPECT_EQ(result->Keywords(), keywords[""]); |
| EXPECT_EQ(result->MimeTypes(), mime_types); |
| EXPECT_EQ(result->NoDisplay(), no_display); |
| EXPECT_EQ(result->Exec(), exec); |
| EXPECT_EQ(result->ExecutableFileName(), executable_file_name); |
| EXPECT_EQ(result->PackageId(), package_id); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, Observer) { |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app 1", "vm", "container"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("app 2"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("app 3"); |
| std::string app_id_1 = |
| crostini::CrostiniTestHelper::GenerateAppId("app 1", "vm", "container"); |
| std::string app_id_2 = |
| crostini::CrostiniTestHelper::GenerateAppId("app 2", "vm", "container"); |
| std::string app_id_3 = |
| crostini::CrostiniTestHelper::GenerateAppId("app 3", "vm", "container"); |
| std::string app_id_4 = |
| crostini::CrostiniTestHelper::GenerateAppId("app 4", "vm", "container"); |
| |
| Observer observer; |
| service()->AddObserver(&observer); |
| EXPECT_CALL( |
| observer, |
| OnRegistryUpdated( |
| service(), |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA, |
| testing::IsEmpty(), testing::IsEmpty(), |
| testing::UnorderedElementsAre(app_id_1, app_id_2, app_id_3))); |
| service()->UpdateApplicationList(app_list); |
| |
| // Rename desktop file for "app 2" to "app 4" (deletion+insertion) |
| app_list.mutable_apps(1)->set_desktop_file_id("app 4"); |
| // Rename name for "app 3" to "banana" |
| app_list.mutable_apps(2)->mutable_name()->mutable_values(0)->set_value( |
| "banana"); |
| EXPECT_CALL( |
| observer, |
| OnRegistryUpdated( |
| service(), |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA, |
| testing::ElementsAre(app_id_3), testing::ElementsAre(app_id_2), |
| testing::ElementsAre(app_id_4))); |
| service()->UpdateApplicationList(app_list); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, ObserverForPvmDefault) { |
| ApplicationList app_list = crostini::CrostiniTestHelper::BasicAppList( |
| "app 1", "PvmDefault", "container"); |
| app_list.set_vm_type(vm_tools::apps::ApplicationList_VmType_PLUGIN_VM); |
| std::string app_id_1 = crostini::CrostiniTestHelper::GenerateAppId( |
| "app 1", "PvmDefault", "container"); |
| |
| Observer observer; |
| service()->AddObserver(&observer); |
| |
| // Observers should be called when apps are added or updated. |
| EXPECT_CALL( |
| observer, |
| OnRegistryUpdated( |
| service(), |
| GuestOsRegistryService::VmType::ApplicationList_VmType_PLUGIN_VM, |
| testing::IsEmpty(), testing::IsEmpty(), |
| testing::UnorderedElementsAre(app_id_1))) |
| .Times(1); |
| service()->UpdateApplicationList(app_list); |
| |
| // Observers should be called when apps are removed. |
| EXPECT_CALL( |
| observer, |
| OnRegistryUpdated( |
| service(), |
| GuestOsRegistryService::VmType::ApplicationList_VmType_PLUGIN_VM, |
| testing::IsEmpty(), testing::UnorderedElementsAre(app_id_1), |
| testing::IsEmpty())) |
| .Times(1); |
| service()->ClearApplicationList( |
| GuestOsRegistryService::VmType::ApplicationList_VmType_PLUGIN_VM, |
| "PvmDefault", ""); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, ZeroAppsInstalledHistogram) { |
| base::HistogramTester histogram_tester; |
| |
| RecreateService(); |
| |
| // Check that there are no apps installed. |
| histogram_tester.ExpectUniqueSample(kCrostiniAppsInstalledHistogram, 0, 1); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, NAppsInstalledHistogram) { |
| base::HistogramTester histogram_tester; |
| |
| // Set up an app list with the expected number of apps. |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app 0", "vm", "container"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("app 1"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("app 2"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("app 3"); |
| |
| // Add apps that should not be counted. |
| App app4 = crostini::CrostiniTestHelper::BasicApp("no display app 4"); |
| app4.set_no_display(true); |
| *app_list.add_apps() = app4; |
| |
| App app5 = crostini::CrostiniTestHelper::BasicApp("no display app 5"); |
| app5.set_no_display(true); |
| *app_list.add_apps() = app5; |
| |
| // Force the registry to have a prefs entry for the Terminal. |
| service()->AppLaunched(crostini::kCrostiniTerminalSystemAppId); |
| |
| // Update the list of apps so that they can be counted. |
| service()->UpdateApplicationList(app_list); |
| |
| RecreateService(); |
| |
| histogram_tester.ExpectUniqueSample(kCrostiniAppsInstalledHistogram, 4, 1); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, PluginVmAppsInstalledHistogram) { |
| base::HistogramTester histogram_tester; |
| |
| plugin_vm::PluginVmTestHelper test_helper(profile()); |
| test_helper.AllowPluginVm(); |
| |
| // Plugin VM needs to be enabled before we start counting. |
| RecreateService(); |
| histogram_tester.ExpectTotalCount(kPluginVmAppsInstalledHistogram, 0); |
| |
| test_helper.EnablePluginVm(); |
| // Set up an app list with the expected number of apps. |
| ApplicationList app_list = crostini::CrostiniTestHelper::BasicAppList( |
| "app 1", "PvmDefault", "container"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("app 2"); |
| app_list.set_vm_type(vm_tools::apps::ApplicationList_VmType_PLUGIN_VM); |
| service()->UpdateApplicationList(app_list); |
| |
| RecreateService(); |
| |
| histogram_tester.ExpectUniqueSample(kPluginVmAppsInstalledHistogram, 2, 1); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, InstallAndLaunchTime) { |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm", "container"); |
| std::string app_id = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm", "container"); |
| test_clock_.Advance(base::TimeDelta::FromHours(1)); |
| |
| Observer observer; |
| service()->AddObserver(&observer); |
| EXPECT_CALL( |
| observer, |
| OnRegistryUpdated( |
| service(), |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA, |
| testing::IsEmpty(), testing::IsEmpty(), |
| testing::ElementsAre(app_id))); |
| service()->UpdateApplicationList(app_list); |
| |
| absl::optional<GuestOsRegistryService::Registration> result = |
| service()->GetRegistration(app_id); |
| base::Time install_time = test_clock_.Now(); |
| EXPECT_EQ(result->InstallTime(), install_time); |
| EXPECT_EQ(result->LastLaunchTime(), base::Time()); |
| |
| // UpdateApplicationList with nothing changed. Times shouldn't be updated and |
| // the observer shouldn't fire. |
| test_clock_.Advance(base::TimeDelta::FromHours(1)); |
| EXPECT_CALL(observer, OnRegistryUpdated(_, _, _, _, _)).Times(0); |
| service()->UpdateApplicationList(app_list); |
| result = service()->GetRegistration(app_id); |
| EXPECT_EQ(result->InstallTime(), install_time); |
| EXPECT_EQ(result->LastLaunchTime(), base::Time()); |
| |
| // Launch the app |
| test_clock_.Advance(base::TimeDelta::FromHours(1)); |
| service()->AppLaunched(app_id); |
| result = service()->GetRegistration(app_id); |
| EXPECT_EQ(result->InstallTime(), install_time); |
| EXPECT_EQ(result->LastLaunchTime(), |
| base::Time() + base::TimeDelta::FromHours(3)); |
| |
| // The install time shouldn't change if fields change. |
| test_clock_.Advance(base::TimeDelta::FromHours(1)); |
| app_list.mutable_apps(0)->set_no_display(true); |
| EXPECT_CALL( |
| observer, |
| OnRegistryUpdated( |
| service(), |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA, |
| testing::ElementsAre(app_id), testing::IsEmpty(), |
| testing::IsEmpty())); |
| service()->UpdateApplicationList(app_list); |
| result = service()->GetRegistration(app_id); |
| EXPECT_EQ(result->InstallTime(), install_time); |
| EXPECT_EQ(result->LastLaunchTime(), |
| base::Time() + base::TimeDelta::FromHours(3)); |
| } |
| |
| // Test that UpdateApplicationList doesn't clobber apps from different VMs or |
| // containers. |
| TEST_F(GuestOsRegistryServiceTest, MultipleContainers) { |
| service()->UpdateApplicationList( |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm 1", "container 1")); |
| service()->UpdateApplicationList( |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm 1", "container 2")); |
| service()->UpdateApplicationList( |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm 2", "container 1")); |
| std::string app_id_1 = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm 1", "container 1"); |
| std::string app_id_2 = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm 1", "container 2"); |
| std::string app_id_3 = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm 2", "container 1"); |
| |
| EXPECT_THAT( |
| GetRegisteredAppIds(), |
| testing::UnorderedElementsAre(app_id_1, app_id_2, app_id_3, |
| crostini::kCrostiniTerminalSystemAppId)); |
| |
| // Clobber app_id_2 |
| service()->UpdateApplicationList(crostini::CrostiniTestHelper::BasicAppList( |
| "app 2", "vm 1", "container 2")); |
| std::string new_app_id = crostini::CrostiniTestHelper::GenerateAppId( |
| "app 2", "vm 1", "container 2"); |
| |
| EXPECT_THAT( |
| GetRegisteredAppIds(), |
| testing::UnorderedElementsAre(app_id_1, app_id_3, new_app_id, |
| crostini::kCrostiniTerminalSystemAppId)); |
| } |
| |
| // Test that ClearApplicationList works, and only removes apps from the |
| // specified VM. |
| TEST_F(GuestOsRegistryServiceTest, ClearApplicationList) { |
| service()->UpdateApplicationList( |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm 1", "container 1")); |
| service()->UpdateApplicationList( |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm 1", "container 2")); |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm 2", "container 1"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("app 2"); |
| service()->UpdateApplicationList(app_list); |
| std::string app_id_1 = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm 1", "container 1"); |
| std::string app_id_2 = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm 1", "container 2"); |
| std::string app_id_3 = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm 2", "container 1"); |
| std::string app_id_4 = crostini::CrostiniTestHelper::GenerateAppId( |
| "app 2", "vm 2", "container 1"); |
| |
| EXPECT_THAT( |
| GetRegisteredAppIds(), |
| testing::UnorderedElementsAre(app_id_1, app_id_2, app_id_3, app_id_4, |
| crostini::kCrostiniTerminalSystemAppId)); |
| |
| service()->ClearApplicationList( |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA, "vm 2", |
| ""); |
| |
| EXPECT_THAT(GetRegisteredAppIds(), |
| testing::UnorderedElementsAre( |
| app_id_1, app_id_2, crostini::kCrostiniTerminalSystemAppId)); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, IsScaledReturnFalseWhenNotSet) { |
| std::string app_id = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm", "container"); |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm", "container"); |
| service()->UpdateApplicationList(app_list); |
| absl::optional<GuestOsRegistryService::Registration> registration = |
| service()->GetRegistration(app_id); |
| EXPECT_TRUE(registration.has_value()); |
| EXPECT_FALSE(registration.value().IsScaled()); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, SetScaledWorks) { |
| std::string app_id = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm", "container"); |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm", "container"); |
| service()->UpdateApplicationList(app_list); |
| service()->SetAppScaled(app_id, true); |
| absl::optional<GuestOsRegistryService::Registration> registration = |
| service()->GetRegistration(app_id); |
| EXPECT_TRUE(registration.has_value()); |
| EXPECT_TRUE(registration.value().IsScaled()); |
| service()->SetAppScaled(app_id, false); |
| registration = service()->GetRegistration(app_id); |
| EXPECT_TRUE(registration.has_value()); |
| EXPECT_FALSE(registration.value().IsScaled()); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, SetAndGetRegistrationKeywords) { |
| std::map<std::string, std::set<std::string>> keywords = { |
| {"", {"very", "awesome"}}, |
| {"fr", {"sum", "ward"}}, |
| {"ge", {"extra", "average"}}, |
| {"te", {"not", "terrible"}}}; |
| std::string app_id = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm", "container"); |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm", "container"); |
| |
| for (const auto& localized_keywords : keywords) { |
| auto* keywords_with_locale = |
| app_list.mutable_apps(0)->mutable_keywords()->add_values(); |
| keywords_with_locale->set_locale(localized_keywords.first); |
| for (const auto& localized_keyword : localized_keywords.second) { |
| keywords_with_locale->add_value(localized_keyword); |
| } |
| } |
| service()->UpdateApplicationList(app_list); |
| |
| absl::optional<GuestOsRegistryService::Registration> result = |
| service()->GetRegistration(app_id); |
| g_browser_process->SetApplicationLocale(""); |
| EXPECT_EQ(result->Keywords(), keywords[""]); |
| g_browser_process->SetApplicationLocale("fr"); |
| EXPECT_EQ(result->Keywords(), keywords["fr"]); |
| g_browser_process->SetApplicationLocale("ge"); |
| EXPECT_EQ(result->Keywords(), keywords["ge"]); |
| g_browser_process->SetApplicationLocale("te"); |
| EXPECT_EQ(result->Keywords(), keywords["te"]); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, SetAndGetRegistrationExec) { |
| std::string exec = "execName --extra-arg=true"; |
| std::string app_id_valid_exec = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm", "container"); |
| std::string app_id_no_exec = |
| crostini::CrostiniTestHelper::GenerateAppId("noExec", "vm", "container"); |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm", "container"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("noExec"); |
| |
| app_list.mutable_apps(0)->set_exec(exec); |
| service()->UpdateApplicationList(app_list); |
| |
| absl::optional<GuestOsRegistryService::Registration> result_valid_exec = |
| service()->GetRegistration(app_id_valid_exec); |
| absl::optional<GuestOsRegistryService::Registration> result_no_exec = |
| service()->GetRegistration(app_id_no_exec); |
| EXPECT_EQ(result_valid_exec->Exec(), exec); |
| EXPECT_EQ(result_no_exec->Exec(), ""); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, SetAndGetRegistrationExecutableFileName) { |
| std::string executable_file_name = "myExec"; |
| std::string app_id_valid_exec = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm", "container"); |
| std::string app_id_no_exec = |
| crostini::CrostiniTestHelper::GenerateAppId("noExec", "vm", "container"); |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm", "container"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("noExec"); |
| |
| app_list.mutable_apps(0)->set_executable_file_name(executable_file_name); |
| service()->UpdateApplicationList(app_list); |
| |
| absl::optional<GuestOsRegistryService::Registration> result_valid_exec = |
| service()->GetRegistration(app_id_valid_exec); |
| absl::optional<GuestOsRegistryService::Registration> result_no_exec = |
| service()->GetRegistration(app_id_no_exec); |
| EXPECT_EQ(result_valid_exec->ExecutableFileName(), executable_file_name); |
| EXPECT_EQ(result_no_exec->ExecutableFileName(), ""); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, SetAndGetPackageId) { |
| std::string package_id = |
| "vim;2:8.0.0197-4+deb9u1;amd64;installed:debian-stable"; |
| std::string app_id_valid_package_id = |
| crostini::CrostiniTestHelper::GenerateAppId("app", "vm", "container"); |
| std::string app_id_no_package_id = |
| crostini::CrostiniTestHelper::GenerateAppId("noPackageId", "vm", |
| "container"); |
| ApplicationList app_list = |
| crostini::CrostiniTestHelper::BasicAppList("app", "vm", "container"); |
| *app_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("noPackageId"); |
| |
| app_list.mutable_apps(0)->set_package_id(package_id); |
| service()->UpdateApplicationList(app_list); |
| |
| absl::optional<GuestOsRegistryService::Registration> result_valid_package_id = |
| service()->GetRegistration(app_id_valid_package_id); |
| absl::optional<GuestOsRegistryService::Registration> result_no_package_id = |
| service()->GetRegistration(app_id_no_package_id); |
| EXPECT_EQ(result_valid_package_id->PackageId(), package_id); |
| EXPECT_EQ(result_no_package_id->PackageId(), ""); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, MigrateTerminal) { |
| // Add prefs entry for the deleted terminal. |
| base::DictionaryValue registry; |
| registry.SetKey(crostini::kCrostiniDeletedTerminalId, |
| base::DictionaryValue()); |
| profile()->GetPrefs()->Set(guest_os::prefs::kGuestOsRegistry, |
| std::move(registry)); |
| |
| // Only current terminal returned. |
| RecreateService(); |
| EXPECT_THAT( |
| GetRegisteredAppIds(), |
| testing::UnorderedElementsAre(crostini::kCrostiniTerminalSystemAppId)); |
| |
| // Deleted terminal removed from prefs. |
| EXPECT_FALSE(profile() |
| ->GetPrefs() |
| ->GetDictionary(guest_os::prefs::kGuestOsRegistry) |
| ->HasKey(crostini::kCrostiniDeletedTerminalId)); |
| } |
| |
| // Validates crash fix from crbug.com/1113477. |
| TEST_F(GuestOsRegistryServiceTest, TerminalPrefsAppMerge) { |
| // Add prefs entry for terminal. |
| base::DictionaryValue registry; |
| registry.SetKey(crostini::kCrostiniTerminalSystemAppId, |
| base::DictionaryValue()); |
| profile()->GetPrefs()->Set(guest_os::prefs::kGuestOsRegistry, |
| std::move(registry)); |
| |
| // Pref values should merge with app values, and reading Terminal VmName |
| // should not crash. |
| bool terminal_found = false; |
| for (const auto& pair : service()->GetAllRegisteredApps()) { |
| const auto& registration = pair.second; |
| if (registration.app_id() == crostini::kCrostiniTerminalSystemAppId) { |
| terminal_found = true; |
| EXPECT_EQ(crostini::kCrostiniDefaultVmName, registration.VmName()); |
| } |
| } |
| EXPECT_TRUE(terminal_found); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, GetEnabledApps) { |
| crostini::FakeCrostiniFeatures fake_crostini_features; |
| plugin_vm::FakePluginVmFeatures fake_plugin_vm_features; |
| |
| ApplicationList crostini_list; |
| crostini_list.set_vm_type( |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA); |
| crostini_list.set_vm_name("termina"); |
| crostini_list.set_container_name("penguin"); |
| *crostini_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("c"); |
| std::string c = |
| crostini::CrostiniTestHelper::GenerateAppId("c", "termina", "penguin"); |
| const std::string& t = crostini::kCrostiniTerminalSystemAppId; |
| service()->UpdateApplicationList(crostini_list); |
| |
| ApplicationList plugin_vm_list; |
| plugin_vm_list.set_vm_type( |
| GuestOsRegistryService::VmType::ApplicationList_VmType_PLUGIN_VM); |
| plugin_vm_list.set_vm_name("PvmDefault"); |
| plugin_vm_list.set_container_name("penguin"); |
| *plugin_vm_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("p"); |
| std::string p = |
| crostini::CrostiniTestHelper::GenerateAppId("p", "PvmDefault", "penguin"); |
| service()->UpdateApplicationList(plugin_vm_list); |
| |
| // All enabled. |
| fake_crostini_features.set_enabled(true); |
| fake_plugin_vm_features.set_enabled(true); |
| EXPECT_THAT(GetRegisteredAppIds(), testing::UnorderedElementsAre(t, p, c)); |
| EXPECT_THAT(GetEnabledAppIds(), testing::UnorderedElementsAre(t, p, c)); |
| |
| // Crostini disabled. |
| fake_crostini_features.set_enabled(false); |
| fake_plugin_vm_features.set_enabled(true); |
| EXPECT_THAT(GetRegisteredAppIds(), testing::UnorderedElementsAre(t, p, c)); |
| EXPECT_THAT(GetEnabledAppIds(), testing::UnorderedElementsAre(p)); |
| |
| // Plugin VM disabled. |
| fake_crostini_features.set_enabled(true); |
| fake_plugin_vm_features.set_enabled(false); |
| EXPECT_THAT(GetRegisteredAppIds(), testing::UnorderedElementsAre(t, p, c)); |
| EXPECT_THAT(GetEnabledAppIds(), testing::UnorderedElementsAre(t, c)); |
| |
| // All disabled. |
| fake_crostini_features.set_enabled(false); |
| fake_plugin_vm_features.set_enabled(false); |
| EXPECT_THAT(GetRegisteredAppIds(), testing::UnorderedElementsAre(t, p, c)); |
| EXPECT_THAT(GetEnabledAppIds(), testing::IsEmpty()); |
| } |
| |
| TEST_F(GuestOsRegistryServiceTest, PluginVmNameSuffix) { |
| ApplicationList crostini_list; |
| crostini_list.set_vm_type( |
| GuestOsRegistryService::VmType::ApplicationList_VmType_TERMINA); |
| crostini_list.set_vm_name("termina"); |
| crostini_list.set_container_name("penguin"); |
| *crostini_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("c"); |
| std::string c = |
| crostini::CrostiniTestHelper::GenerateAppId("c", "termina", "penguin"); |
| service()->UpdateApplicationList(crostini_list); |
| |
| ApplicationList plugin_vm_list; |
| plugin_vm_list.set_vm_type( |
| GuestOsRegistryService::VmType::ApplicationList_VmType_PLUGIN_VM); |
| plugin_vm_list.set_vm_name("PvmDefault"); |
| plugin_vm_list.set_container_name("penguin"); |
| *plugin_vm_list.add_apps() = crostini::CrostiniTestHelper::BasicApp("p"); |
| std::string p = |
| crostini::CrostiniTestHelper::GenerateAppId("p", "PvmDefault", "penguin"); |
| service()->UpdateApplicationList(plugin_vm_list); |
| |
| // Crostini apps have name unchanged, PluginVM has ' (Windows)' suffix. |
| EXPECT_EQ("c", service()->GetRegistration(c)->Name()); |
| EXPECT_EQ("p (Windows)", service()->GetRegistration(p)->Name()); |
| } |
| |
| } // namespace guest_os |