| // 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/installer/util/helper.h" |
| |
| #include <windows.h> |
| |
| #include <shlobj.h> |
| |
| #include <optional> |
| #include <string_view> |
| |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/path_service.h" |
| #include "base/test/scoped_path_override.h" |
| #include "base/test/test_reg_util_win.h" |
| #include "base/values.h" |
| #include "base/version.h" |
| #include "base/win/registry.h" |
| #include "build/build_config.h" |
| #include "chrome/install_static/install_util.h" |
| #include "chrome/install_static/test/scoped_install_details.h" |
| #include "chrome/installer/util/google_update_constants.h" |
| #include "chrome/installer/util/initial_preferences.h" |
| #include "chrome/installer/util/util_constants.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace installer { |
| |
| namespace { |
| |
| // A helper that overrides an environment variable for the lifetime of an |
| // instance. |
| class ScopedEnvironmentOverride { |
| public: |
| ScopedEnvironmentOverride(std::wstring_view name, const wchar_t* new_value) |
| : name_(name) { |
| std::array<wchar_t, MAX_PATH> value; |
| value[0] = L'\0'; |
| DWORD len = |
| ::GetEnvironmentVariableW(name_.c_str(), value.data(), value.size()); |
| if (len > 0 && len < value.size()) { |
| old_value_.emplace(value.data(), len); |
| } |
| ::SetEnvironmentVariableW(name_.c_str(), new_value); |
| } |
| ~ScopedEnvironmentOverride() { |
| ::SetEnvironmentVariableW(name_.c_str(), |
| old_value_ ? old_value_->c_str() : nullptr); |
| } |
| |
| private: |
| const std::wstring name_; |
| std::optional<std::wstring> old_value_; |
| }; |
| |
| } // namespace |
| |
| class GetInstalledDirectoryTest : public testing::TestWithParam<bool> { |
| protected: |
| void SetUp() override { |
| ASSERT_TRUE(random_.CreateUniqueTempDir()); |
| ASSERT_NO_FATAL_FAILURE( |
| registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE)); |
| ASSERT_NO_FATAL_FAILURE( |
| registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER)); |
| } |
| |
| static bool is_system_level() { return GetParam(); } |
| base::FilePath random_path() const { return random_.GetPath(); } |
| |
| static base::win::RegKey GetClientsRegKey() { |
| return base::win::RegKey( |
| is_system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, |
| install_static::GetClientsKeyPath().c_str(), |
| KEY_SET_VALUE | KEY_WOW64_32KEY); |
| } |
| |
| static base::win::RegKey GetClientStateRegKey() { |
| return base::win::RegKey( |
| is_system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, |
| install_static::GetClientStateKeyPath().c_str(), |
| KEY_SET_VALUE | KEY_WOW64_32KEY); |
| } |
| |
| private: |
| base::ScopedTempDir random_; |
| registry_util::RegistryOverrideManager registry_override_manager_; |
| }; |
| |
| TEST_P(GetInstalledDirectoryTest, NoRegistryValue) { |
| EXPECT_EQ(GetInstalledDirectory(is_system_level()), base::FilePath()); |
| } |
| |
| TEST_P(GetInstalledDirectoryTest, RegistryValueSet) { |
| const base::FilePath install_path = |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir); |
| ASSERT_TRUE(base::CreateDirectory(install_path)); |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| install_path.AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| |
| EXPECT_EQ(GetInstalledDirectory(is_system_level()), install_path); |
| } |
| |
| TEST_P(GetInstalledDirectoryTest, NoDirectory) { |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir) |
| .AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| EXPECT_EQ(GetInstalledDirectory(is_system_level()), base::FilePath()); |
| } |
| |
| TEST_P(GetInstalledDirectoryTest, ReferencesParent) { |
| const base::FilePath install_path = |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir); |
| ASSERT_TRUE(base::CreateDirectory(install_path)); |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| install_path |
| .AppendASCII("1.0.0.0\\Installer\\..\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| |
| EXPECT_EQ(GetInstalledDirectory(is_system_level()), base::FilePath()); |
| } |
| |
| TEST_P(GetInstalledDirectoryTest, NotAbsolute) { |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| base::FilePath(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir) |
| .AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| |
| EXPECT_EQ(GetInstalledDirectory(is_system_level()), base::FilePath()); |
| } |
| |
| TEST_P(GetInstalledDirectoryTest, AtRoot) { |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ( |
| client_state_key.WriteValue( |
| kUninstallStringField, |
| base::FilePath(FILE_PATH_LITERAL("C:\\1.0.0.0\\Installer\\setup.exe")) |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| |
| EXPECT_EQ(GetInstalledDirectory(is_system_level()), base::FilePath()); |
| } |
| |
| TEST_P(GetInstalledDirectoryTest, RegistryValueSetWrongScope) { |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir) |
| .AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| EXPECT_EQ(GetInstalledDirectory(!is_system_level()), base::FilePath()); |
| } |
| |
| TEST_P(GetInstalledDirectoryTest, RegistryValueSetNoProductVersion) { |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir) |
| .AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| EXPECT_EQ(GetInstalledDirectory(is_system_level()), base::FilePath()); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(UserLevelTest, |
| GetInstalledDirectoryTest, |
| testing::Values(false)); |
| INSTANTIATE_TEST_SUITE_P(SystemLevelTest, |
| GetInstalledDirectoryTest, |
| testing::Values(true)); |
| |
| class GetDefaultChromeInstallPathTest : public testing::TestWithParam<bool> { |
| protected: |
| void SetUp() override { |
| ASSERT_TRUE(program_files_.CreateUniqueTempDir()); |
| ASSERT_TRUE(program_files_x86_.CreateUniqueTempDir()); |
| ASSERT_TRUE(local_app_data_.CreateUniqueTempDir()); |
| program_files_override_.emplace(base::DIR_PROGRAM_FILES, |
| program_files_path()); |
| program_files_x86_override_.emplace(base::DIR_PROGRAM_FILESX86, |
| program_files_x86_path()); |
| local_data_app_override_.emplace(base::DIR_LOCAL_APP_DATA, |
| local_app_data_path()); |
| } |
| |
| static bool is_system_level() { return GetParam(); } |
| base::FilePath program_files_path() const { return program_files_.GetPath(); } |
| base::FilePath program_files_x86_path() const { |
| return program_files_x86_.GetPath(); |
| } |
| base::FilePath local_app_data_path() const { |
| return local_app_data_.GetPath(); |
| } |
| |
| base::FilePath GetExpectedPath(bool system_level) const { |
| auto path = system_level ? program_files_path() : local_app_data_path(); |
| return path.Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir); |
| } |
| |
| private: |
| base::ScopedTempDir program_files_; |
| base::ScopedTempDir program_files_x86_; |
| base::ScopedTempDir local_app_data_; |
| std::optional<base::ScopedPathOverride> program_files_override_; |
| std::optional<base::ScopedPathOverride> program_files_x86_override_; |
| std::optional<base::ScopedPathOverride> local_data_app_override_; |
| }; |
| |
| // Tests that the PathService is used to get the default install path. |
| TEST_P(GetDefaultChromeInstallPathTest, PathService) { |
| EXPECT_EQ(GetDefaultChromeInstallPath(is_system_level()), |
| GetExpectedPath(is_system_level())); |
| } |
| |
| // Tests that the environment variable fallback is used if the PathService |
| // returns a path that doesn't exist. |
| TEST_P(GetDefaultChromeInstallPathTest, EnvironmentFallback) { |
| // Override the relevant paths with directories that do not exist so that the |
| // env var fallback is reached. |
| base::ScopedPathOverride bad_program_files_override( |
| base::DIR_PROGRAM_FILES, program_files_path().AppendASCII("doesnotexist"), |
| /*is_absolute=*/true, /*create=*/false); |
| base::ScopedPathOverride bad_program_files_x86_override( |
| base::DIR_PROGRAM_FILESX86, |
| program_files_x86_path().AppendASCII("doesnotexist"), |
| /*is_absolute=*/true, /*create=*/false); |
| base::ScopedPathOverride bad_local_ap_data_override( |
| base::DIR_LOCAL_APP_DATA, |
| local_app_data_path().AppendASCII("doesnotexist"), |
| /*is_absolute=*/true, /*create=*/false); |
| |
| ScopedEnvironmentOverride program_files_env( |
| L"PROGRAMFILES", program_files_path().value().c_str()); |
| ScopedEnvironmentOverride program_files_x86_env( |
| L"PROGRAMFILES(X86)", program_files_x86_path().value().c_str()); |
| ScopedEnvironmentOverride local_app_data_env( |
| L"LOCALAPPDATA", local_app_data_path().value().c_str()); |
| |
| EXPECT_EQ(GetDefaultChromeInstallPath(is_system_level()), |
| GetExpectedPath(is_system_level())); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(UserLevelTest, |
| GetDefaultChromeInstallPathTest, |
| testing::Values(false)); |
| INSTANTIATE_TEST_SUITE_P(SystemLevelTest, |
| GetDefaultChromeInstallPathTest, |
| testing::Values(true)); |
| |
| struct Params { |
| Params(bool system_level, std::optional<int> target_dir_key) |
| : system_level(system_level), target_dir_key(target_dir_key) {} |
| bool system_level; |
| std::optional<int> target_dir_key; |
| }; |
| |
| // Tests GetChromeInstallPath with a params object that contains a boolean |
| // |system_level| which is |true| if the test must use system-level values or |
| // |false| it the test must use user-level values, and a |target_dir| path in |
| // which the installation should be made. |
| class GetChromeInstallPathWithPrefsTest |
| : public testing::TestWithParam<Params> { |
| protected: |
| void SetUp() override { |
| ASSERT_TRUE(program_files_.CreateUniqueTempDir()); |
| ASSERT_TRUE(program_files_x86_.CreateUniqueTempDir()); |
| ASSERT_TRUE(random_.CreateUniqueTempDir()); |
| ASSERT_TRUE(local_app_data_.CreateUniqueTempDir()); |
| ASSERT_NO_FATAL_FAILURE( |
| registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE)); |
| ASSERT_NO_FATAL_FAILURE( |
| registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER)); |
| program_files_override_.emplace(base::DIR_PROGRAM_FILES, |
| program_files_path()); |
| program_files_x86_override_.emplace(base::DIR_PROGRAM_FILESX86, |
| program_files_x86_path()); |
| local_data_app_override_.emplace(base::DIR_LOCAL_APP_DATA, |
| local_app_data_path()); |
| } |
| |
| base::FilePath random_path() const { return random_.GetPath(); } |
| base::FilePath program_files_path() const { return program_files_.GetPath(); } |
| base::FilePath program_files_x86_path() const { |
| return program_files_x86_.GetPath(); |
| } |
| base::FilePath local_app_data_path() const { |
| return local_app_data_.GetPath(); |
| } |
| static bool is_system_level() { return GetParam().system_level; } |
| |
| base::FilePath GetExpectedPath(bool system_level) { |
| auto path = system_level ? program_files_path() : local_app_data_path(); |
| return path.Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir); |
| } |
| |
| static base::win::RegKey GetClientsRegKey() { |
| return base::win::RegKey( |
| is_system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, |
| install_static::GetClientsKeyPath().c_str(), |
| KEY_SET_VALUE | KEY_WOW64_32KEY); |
| } |
| |
| static base::win::RegKey GetClientStateRegKey() { |
| return base::win::RegKey( |
| is_system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, |
| install_static::GetClientStateKeyPath().c_str(), |
| KEY_SET_VALUE | KEY_WOW64_32KEY); |
| } |
| |
| base::FilePath GetExpectedPathForSetup(bool system_level, |
| base::FilePath target_dir) { |
| if (system_level && !target_dir.empty() && |
| (target_dir == program_files_path() || |
| target_dir == program_files_x86_path())) { |
| return target_dir.Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir); |
| } |
| return GetExpectedPath(system_level); |
| } |
| |
| static base::FilePath target_dir() { |
| base::FilePath result; |
| if (GetParam().target_dir_key.has_value()) |
| base::PathService::Get(GetParam().target_dir_key.value(), &result); |
| return result; |
| } |
| |
| static base::Value::Dict prefs_json() { |
| base::FilePath result; |
| if (GetParam().target_dir_key.has_value()) |
| base::PathService::Get(GetParam().target_dir_key.value(), &result); |
| base::Value::Dict distribution; |
| distribution.SetByDottedPath("distribution.program_files_dir", |
| result.AsUTF8Unsafe()); |
| return distribution; |
| } |
| |
| private: |
| base::ScopedTempDir program_files_; |
| base::ScopedTempDir program_files_x86_; |
| base::ScopedTempDir random_; |
| base::ScopedTempDir local_app_data_; |
| registry_util::RegistryOverrideManager registry_override_manager_; |
| std::optional<base::ScopedPathOverride> program_files_override_; |
| std::optional<base::ScopedPathOverride> program_files_x86_override_; |
| std::optional<base::ScopedPathOverride> local_data_app_override_; |
| }; |
| |
| TEST_P(GetChromeInstallPathWithPrefsTest, NoRegistryValue) { |
| EXPECT_EQ(GetChromeInstallPathWithPrefs(is_system_level(), |
| InitialPreferences(prefs_json())), |
| GetExpectedPathForSetup(is_system_level(), target_dir())); |
| } |
| |
| TEST_P(GetChromeInstallPathWithPrefsTest, RegistryValueSet) { |
| const base::FilePath install_path = |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir); |
| ASSERT_TRUE(base::CreateDirectory(install_path)); |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| install_path.AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| EXPECT_EQ(GetChromeInstallPathWithPrefs(is_system_level(), |
| InitialPreferences(prefs_json())), |
| install_path); |
| } |
| |
| TEST_P(GetChromeInstallPathWithPrefsTest, RegistryValueSetWrongScope) { |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir) |
| .AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_key(GetClientsRegKey()); |
| ASSERT_EQ(client_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| EXPECT_EQ(GetChromeInstallPathWithPrefs(!is_system_level(), |
| InitialPreferences(prefs_json())), |
| GetExpectedPathForSetup(!is_system_level(), target_dir())); |
| } |
| |
| TEST_P(GetChromeInstallPathWithPrefsTest, RegistryValueSetNoProductVersion) { |
| base::win::RegKey client_state_key(GetClientStateRegKey()); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| random_path() |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir) |
| .AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| EXPECT_EQ(GetChromeInstallPathWithPrefs(is_system_level(), |
| InitialPreferences(prefs_json())), |
| GetExpectedPathForSetup(is_system_level(), target_dir())); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| UserLevelX86SetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(false, base::DIR_PROGRAM_FILESX86))); |
| |
| INSTANTIATE_TEST_SUITE_P( |
| UserLevelX64SetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(false, base::DIR_PROGRAM_FILES))); |
| |
| INSTANTIATE_TEST_SUITE_P(UserLevelUnsupportedPathSetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(false, |
| base::DIR_HOME))); |
| |
| INSTANTIATE_TEST_SUITE_P(UserLevelEmptyPathSetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(false, std::nullopt))); |
| |
| INSTANTIATE_TEST_SUITE_P( |
| MachineLevelX86SetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(true, base::DIR_PROGRAM_FILESX86))); |
| |
| INSTANTIATE_TEST_SUITE_P( |
| MachineLevelX64SetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(true, base::DIR_PROGRAM_FILES))); |
| |
| INSTANTIATE_TEST_SUITE_P(MachineLevelUnsupportedPathSetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(true, base::DIR_HOME))); |
| |
| INSTANTIATE_TEST_SUITE_P(MachineLevelEmptyPathSetupTest, |
| GetChromeInstallPathWithPrefsTest, |
| testing::Values<Params>(Params(true, std::nullopt))); |
| |
| class FindInstallPathTest |
| : public ::testing::TestWithParam<std::tuple<bool, int>> { |
| protected: |
| void SetUp() override { |
| ASSERT_TRUE(program_files_.CreateUniqueTempDir()); |
| ASSERT_TRUE(program_files_x86_.CreateUniqueTempDir()); |
| ASSERT_TRUE(program_files_6432_.CreateUniqueTempDir()); |
| ASSERT_TRUE(local_app_data_.CreateUniqueTempDir()); |
| program_files_override_.emplace(base::DIR_PROGRAM_FILES, |
| program_files_path()); |
| program_files_x86_override_.emplace(base::DIR_PROGRAM_FILESX86, |
| program_files_x86_path()); |
| program_files_6432_override_.emplace(base::DIR_PROGRAM_FILES6432, |
| program_files_6432_path()); |
| local_data_app_override_.emplace(base::DIR_LOCAL_APP_DATA, |
| local_app_data_path()); |
| } |
| |
| static bool is_system_level() { return std::get<0>(GetParam()); } |
| static int target_path_key() { return std::get<1>(GetParam()); } |
| base::FilePath program_files_path() const { return program_files_.GetPath(); } |
| base::FilePath program_files_x86_path() const { |
| return program_files_x86_.GetPath(); |
| } |
| base::FilePath program_files_6432_path() const { |
| return program_files_6432_.GetPath(); |
| } |
| base::FilePath local_app_data_path() const { |
| return local_app_data_.GetPath(); |
| } |
| |
| private: |
| base::ScopedTempDir program_files_; |
| base::ScopedTempDir program_files_x86_; |
| base::ScopedTempDir program_files_6432_; |
| base::ScopedTempDir local_app_data_; |
| std::optional<base::ScopedPathOverride> program_files_override_; |
| std::optional<base::ScopedPathOverride> program_files_x86_override_; |
| std::optional<base::ScopedPathOverride> program_files_6432_override_; |
| std::optional<base::ScopedPathOverride> local_data_app_override_; |
| }; |
| |
| // Tests that FindInstallPath returns an empty string when no install directory |
| // is present. |
| TEST_P(FindInstallPathTest, NoDirectory) { |
| EXPECT_EQ(FindInstallPath(is_system_level(), base::Version("1.0.0.0")), |
| base::FilePath()); |
| } |
| |
| // Tests that FindInstallPath returns the path to the installed version |
| // directory. |
| TEST_P(FindInstallPathTest, Installed) { |
| const auto path = base::PathService::CheckedGet(target_path_key()) |
| .Append(install_static::GetChromeInstallSubDirectory()) |
| .Append(kInstallBinaryDir) |
| .Append(L"1.0.0.0"); |
| ASSERT_TRUE(base::CreateDirectoryAndGetError(path, nullptr)); |
| EXPECT_EQ(FindInstallPath(is_system_level(), base::Version("1.0.0.0")), path); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| UserLevelTest, |
| FindInstallPathTest, |
| testing::Values(std::make_tuple(false, base::DIR_LOCAL_APP_DATA))); |
| INSTANTIATE_TEST_SUITE_P( |
| SystemLevelTest, |
| FindInstallPathTest, |
| testing::Values(std::make_tuple(true, base::DIR_PROGRAM_FILES), |
| #if defined(ARCH_CPU_64_BITS) |
| std::make_tuple(true, base::DIR_PROGRAM_FILESX86) |
| #else |
| std::make_tuple(true, base::DIR_PROGRAM_FILES6432) |
| #endif |
| |
| )); |
| |
| class IsCurrentProcessInstalledTest : public testing::TestWithParam<bool> { |
| protected: |
| void SetUp() override { |
| if (GetParam() && !::IsUserAnAdmin()) { |
| GTEST_SKIP() << "Test requires admin rights"; |
| } |
| ASSERT_NO_FATAL_FAILURE(registry_override_manager_.OverrideRegistry( |
| GetParam() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER)); |
| } |
| |
| void SetInstalledDirectory(const base::FilePath& installed_dir) { |
| const HKEY kRoot = GetParam() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| base::win::RegKey clients_key(kRoot, |
| install_static::GetClientsKeyPath().c_str(), |
| KEY_SET_VALUE | KEY_WOW64_32KEY); |
| ASSERT_EQ( |
| clients_key.WriteValue(google_update::kRegVersionField, L"1.0.0.0"), |
| ERROR_SUCCESS); |
| |
| base::win::RegKey client_state_key( |
| kRoot, install_static::GetClientStateKeyPath().c_str(), |
| KEY_SET_VALUE | KEY_WOW64_32KEY); |
| ASSERT_EQ(client_state_key.WriteValue( |
| kUninstallStringField, |
| installed_dir.AppendASCII("1.0.0.0\\Installer\\setup.exe") |
| .value() |
| .c_str()), |
| ERROR_SUCCESS); |
| } |
| |
| private: |
| install_static::ScopedInstallDetails install_details_{ |
| /*system_level=*/GetParam()}; |
| registry_util::RegistryOverrideManager registry_override_manager_; |
| }; |
| |
| // Tests that IsCurrentProcessInstalled returns false when the product is not |
| // registered with the updater. |
| TEST_P(IsCurrentProcessInstalledTest, NotInstalled) { |
| ASSERT_FALSE(IsCurrentProcessInstalled()); |
| } |
| |
| // Tests that IsCurrentProcessInstalled returns false when the product is |
| // registered with the updater but the current exe resides elsewhere. |
| TEST_P(IsCurrentProcessInstalledTest, InstalledNotInDir) { |
| ASSERT_NO_FATAL_FAILURE( |
| SetInstalledDirectory(base::PathService::CheckedGet(base::DIR_TEMP))); |
| |
| ASSERT_FALSE(IsCurrentProcessInstalled()); |
| } |
| |
| // Tests that IsCurrentProcessInstalled returns true when the product is |
| // registered with the updater and the current exe resides in the same dir. |
| TEST_P(IsCurrentProcessInstalledTest, InstalledInDir) { |
| ASSERT_NO_FATAL_FAILURE( |
| SetInstalledDirectory(base::PathService::CheckedGet(base::DIR_EXE))); |
| |
| ASSERT_TRUE(IsCurrentProcessInstalled()); |
| } |
| |
| // Tests that IsCurrentProcessInstalled returns true when the product is |
| // registered with the updater and the current exe resides in a subdir. |
| TEST_P(IsCurrentProcessInstalledTest, InstalledInSubDir) { |
| ASSERT_NO_FATAL_FAILURE(SetInstalledDirectory( |
| base::PathService::CheckedGet(base::DIR_EXE).DirName())); |
| |
| ASSERT_TRUE(IsCurrentProcessInstalled()); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(UserLevelTest, |
| IsCurrentProcessInstalledTest, |
| testing::Values(false)); |
| |
| INSTANTIATE_TEST_SUITE_P(SystemLevelTest, |
| IsCurrentProcessInstalledTest, |
| testing::Values(true)); |
| |
| } // namespace installer |