root/chrome/test/mini_installer_test/installer_test_util.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ToBrowserDistributionType
  2. DeleteInstallDirectory
  3. DeleteRegistryKey
  4. GetChromeInstallDirectory
  5. GetInstallDirectory
  6. GetInstalledProducts
  7. ValidateInstall
  8. GetVersion
  9. Install
  10. Install
  11. LaunchChrome
  12. LaunchIE
  13. UninstallAll
  14. Uninstall
  15. Uninstall
  16. RunAndWaitForCommandToFinish

// Copyright (c) 2012 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/test/mini_installer_test/installer_test_util.h"

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/strings/string_util.h"
#include "base/threading/platform_thread.h"
#include "chrome/common/chrome_result_codes.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/util_constants.h"
#include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

using installer::InstallationValidator;

namespace {

BrowserDistribution::Type ToBrowserDistributionType(
    InstallationValidator::InstallationType type) {
  const int kChromeMask =
      (InstallationValidator::ProductBits::CHROME_SINGLE |
       InstallationValidator::ProductBits::CHROME_MULTI);
  const int kChromeFrameMask =
      (InstallationValidator::ProductBits::CHROME_FRAME_SINGLE |
       InstallationValidator::ProductBits::CHROME_FRAME_MULTI);
  const int kBinariesMask =
      (InstallationValidator::ProductBits::CHROME_MULTI |
       InstallationValidator::ProductBits::CHROME_FRAME_MULTI);
  // Default return is CHROME_BINARIES.
  BrowserDistribution::Type ret_value = BrowserDistribution::CHROME_BINARIES;
  if (type & kChromeMask)
    ret_value = BrowserDistribution::CHROME_BROWSER;
  if (type & kChromeFrameMask)
    ret_value = BrowserDistribution::CHROME_FRAME;
  if (type & kBinariesMask)
    ret_value = BrowserDistribution::CHROME_BINARIES;
  return ret_value;
}

}  // namespace

namespace installer_test {

bool DeleteInstallDirectory(bool system_level,
                            InstallationValidator::InstallationType type) {
  std::string version = GetVersion(type);
  if (version.empty())
    return false;
  base::FilePath path;
  bool has_install_dir = GetInstallDirectory(system_level,
                                             ToBrowserDistributionType(type),
                                             &path);
  if (!has_install_dir || !base::PathExists(path))
    return false;
  path = path.AppendASCII(version);
  return base::DeleteFile(path, true);
}

bool DeleteRegistryKey(bool system_level,
                       InstallationValidator::InstallationType type) {
  BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
      ToBrowserDistributionType(type));
  base::FilePath::StringType key(google_update::kRegPathClients);
  key.push_back(base::FilePath::kSeparators[0]);
  key.append(dist->GetAppGuid());
  HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
  return InstallUtil::DeleteRegistryKey(root, key);
}

bool GetChromeInstallDirectory(bool system_level, base::FilePath* path) {
  return GetInstallDirectory(system_level,
      BrowserDistribution::CHROME_BROWSER, path);
}

bool GetInstallDirectory(bool system_level,
                         BrowserDistribution::Type type, base::FilePath* path) {
  BrowserDistribution* dist =
      BrowserDistribution::GetSpecificDistribution(type);
  *path = installer::GetChromeInstallPath(system_level, dist);
  base::FilePath parent;
  if (system_level)
    PathService::Get(base::DIR_PROGRAM_FILES, &parent);
  else
    PathService::Get(base::DIR_LOCAL_APP_DATA, &parent);
  return parent.IsParent(*path);
}

bool GetInstalledProducts(
    std::vector<installer_test::InstalledProduct>* products) {
  // Clear out the products list.
  products->clear();
  // Check user-level and system-level for products.
  BrowserDistribution* current_dist;
  installer_test::InstalledProduct current_prod;
  for (int i = 0; i < 2; ++i) {
    const bool system_level = (i != 0);
    InstallationValidator::InstallationType type =
        InstallationValidator::NO_PRODUCTS;
    bool is_valid =
        InstallationValidator::ValidateInstallationType(system_level, &type);
    if (type != InstallationValidator::NO_PRODUCTS) {
      current_dist = BrowserDistribution::GetSpecificDistribution(
          ToBrowserDistributionType(type));
      Version version;
      InstallUtil::GetChromeVersion(current_dist, system_level, &version);
      if (version.IsValid()) {
        current_prod.type = type;
        current_prod.version = version.GetString();
        current_prod.system = system_level;
        products->push_back(current_prod);
      }
    }
  }
  return !products->empty();
}

bool ValidateInstall(bool system_level,
                     InstallationValidator::InstallationType expected,
                     const std::string& version) {
  if (GetVersion(expected) != version)
    return false;
  InstallationValidator::InstallationType type;
  InstallationValidator::ValidateInstallationType(system_level, &type);
  if (type == InstallationValidator::NO_PRODUCTS) {
    LOG(ERROR) << "No installed Chrome or Chrome Frame versions found.";
    return false;
  }
  if ((type & expected) == 0) {
    LOG(ERROR) << "Expected type: " << expected << "\n Actual type: " << type;
    return false;
  }
  return true;
}

std::string GetVersion(InstallationValidator::InstallationType product) {
  std::vector<installer_test::InstalledProduct> installed;
  if (GetInstalledProducts(&installed)) {
    for (size_t i = 0; i < installed.size(); ++i) {
      if ((installed[i].type & product) != 0) {
        return installed[i].version;
      }
    }
  }
  return "";
}

bool Install(const base::FilePath& installer) {
  if (!base::PathExists(installer)) {
    LOG(ERROR) << "Installer does not exist: " << installer.MaybeAsASCII();
    return false;
  }
  CommandLine command(installer);
  LOG(INFO) << "Running installer command: "
            << command.GetCommandLineString();
  return installer_test::RunAndWaitForCommandToFinish(command);
}

bool Install(const base::FilePath& installer, const SwitchBuilder& switches) {
  if (!base::PathExists(installer)) {
    LOG(ERROR) << "Installer does not exist: " << installer.MaybeAsASCII();
    return false;
  }
  CommandLine command(installer);
  command.AppendArguments(switches.GetSwitches(), false);
  LOG(INFO) << "Running installer command: "
            << command.GetCommandLineString();
  return installer_test::RunAndWaitForCommandToFinish(command);
}

bool LaunchChrome(bool close_after_launch, bool system_level) {
  base::CleanupProcesses(installer::kChromeExe, base::TimeDelta(),
                         content::RESULT_CODE_HUNG, NULL);
  base::FilePath install_path;
  if (!GetChromeInstallDirectory(
      system_level, &install_path)) {
    LOG(ERROR) << "Could not find Chrome install directory";
    return false;
  }
  install_path = install_path.Append(installer::kChromeExe);
  CommandLine browser(install_path);

  base::FilePath exe = browser.GetProgram();
  LOG(INFO) << "Browser launch command: " << browser.GetCommandLineString();
  base::ProcessHandle chrome;
  if (!base::LaunchProcess(browser, base::LaunchOptions(), &chrome)) {
    LOG(ERROR) << "Could not launch process: " << exe.value();
    return false;
  }
  if (close_after_launch) {
    if (base::KillProcess(chrome, 0, true)) {
      LOG(ERROR) << "Failed to close chrome.exe after launch.";
      return false;
    }
  }
  return true;
}

bool LaunchIE(const std::string& url) {
  base::FilePath browser_path;
  PathService::Get(base::DIR_PROGRAM_FILES, &browser_path);
  browser_path = browser_path.Append(mini_installer_constants::kIELocation);
  browser_path = browser_path.Append(mini_installer_constants::kIEProcessName);

  CommandLine cmd_line(browser_path);
  cmd_line.AppendArg(url);
  return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL);
}

bool UninstallAll() {
  base::CleanupProcesses(installer::kChromeExe, base::TimeDelta(),
                         content::RESULT_CODE_HUNG, NULL);
  base::CleanupProcesses(installer::kChromeFrameHelperExe, base::TimeDelta(),
                         content::RESULT_CODE_HUNG, NULL);
  std::vector<installer_test::InstalledProduct> installed;
  if (!GetInstalledProducts(&installed)) {
    LOG(WARNING) << "No installed products to uninstall.";
    return false;
  }
  bool ret_val = false;
  for (size_t i = 0; i < installed.size(); ++i) {
    if (!Uninstall(installed[i].system, installed[i].type))
      ret_val = false;
  }
  return ret_val;
}

bool Uninstall(bool system_level,
               InstallationValidator::InstallationType type) {
  std::vector<BrowserDistribution::Type> products;
  if (ToBrowserDistributionType(type) !=
      BrowserDistribution::CHROME_BINARIES) {
    products.push_back(ToBrowserDistributionType(type));
  } else {
    products.push_back(BrowserDistribution::CHROME_BROWSER);
    products.push_back(BrowserDistribution::CHROME_FRAME);
  }
  bool ret_val = false;
  for (size_t i = 0; i < products.size(); ++i) {
    if (!Uninstall(system_level, products[i]))
      ret_val = false;
  }
  return ret_val;
}

bool Uninstall(bool system_level,
               BrowserDistribution::Type product) {
  static const int kMultiMask =
      (InstallationValidator::ProductBits::CHROME_MULTI |
       InstallationValidator::ProductBits::CHROME_FRAME_MULTI);
  CommandLine uninstall_cmd(InstallUtil::GetChromeUninstallCmd(system_level,
      product));
  CommandLine::StringType archive =
      uninstall_cmd.GetProgram().DirName().AppendASCII("chrome.7z").value();
  uninstall_cmd.AppendSwitch(installer::switches::kUninstall);
  uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall);
  uninstall_cmd.AppendSwitchNative(
      installer::switches::kInstallArchive, archive);
  if (system_level)
    uninstall_cmd.AppendSwitch(installer::switches::kSystemLevel);
  if ((product & kMultiMask) !=0)
    uninstall_cmd.AppendSwitch(installer::switches::kMultiInstall);
  LOG(INFO) << "Uninstall command: " << uninstall_cmd.GetCommandLineString();
  bool ret_val = RunAndWaitForCommandToFinish(uninstall_cmd);
  // Close IE notification when uninstalling Chrome Frame.
  base::CleanupProcesses(mini_installer_constants::kIEProcessName,
                         base::TimeDelta(),
                         content::RESULT_CODE_HUNG, NULL);
  return ret_val;
}


bool RunAndWaitForCommandToFinish(CommandLine command) {
  if (!base::PathExists(command.GetProgram())) {
    LOG(ERROR) << "Command executable does not exist: "
               << command.GetProgram().MaybeAsASCII();
    return false;
  }
  base::ProcessHandle process;
  if (!base::LaunchProcess(command, base::LaunchOptions(), &process)) {
    LOG(ERROR) << "Failed to launch command: "
               << command.GetCommandLineString();
    return false;
  }
  if (!base::WaitForSingleProcess(process, base::TimeDelta::FromMinutes(1))) {
    LOG(ERROR) << "Launched process did not complete.";
    return false;
  }
  return true;
}

}  // namespace

/* [<][>][^][v][top][bottom][index][help] */