// 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 <windows.h>

#include <fstream>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_reg_util_win.h"
#include "base/version.h"
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/installer/test/alternate_version_generator.h"
#include "chrome/installer/util/fake_installation_state.h"
#include "chrome/installer/util/fake_product_state.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/installation_state.h"
#include "chrome/installer/util/installer_state.h"
#include "chrome/installer/util/master_preferences.h"
#include "chrome/installer/util/product_unittest.h"
#include "chrome/installer/util/util_constants.h"
#include "chrome/installer/util/work_item.h"
#include "testing/gtest/include/gtest/gtest.h"

#include "installer_util_strings.h"  // NOLINT

using base::win::RegKey;
using installer::InstallationState;
using installer::InstallerState;
using installer::MasterPreferences;
using registry_util::RegistryOverrideManager;

class InstallerStateTest : public TestWithTempDirAndDeleteTempOverrideKeys {
 protected:
};

// An installer state on which we can access otherwise protected members.
class MockInstallerState : public InstallerState {
 public:
  MockInstallerState() : InstallerState() { }
  void set_target_path(const base::FilePath& target_path) {
    target_path_ = target_path;
  }
  static bool IsFileInUse(const base::FilePath& file) {
    return InstallerState::IsFileInUse(file);
  }
  const Version& critical_update_version() const {
    return critical_update_version_;
  }
  void GetExistingExeVersions(std::set<std::string>* existing_version_strings) {
    return InstallerState::GetExistingExeVersions(existing_version_strings);
  }
};

// Simple function to dump some text into a new file.
void CreateTextFile(const std::wstring& filename,
                    const std::wstring& contents) {
  std::ofstream file;
  file.open(filename.c_str());
  ASSERT_TRUE(file.is_open());
  file << contents;
  file.close();
}

void BuildSingleChromeState(const base::FilePath& target_dir,
                            MockInstallerState* installer_state) {
  CommandLine cmd_line = CommandLine::FromString(L"setup.exe");
  MasterPreferences prefs(cmd_line);
  InstallationState machine_state;
  machine_state.Initialize();
  installer_state->Initialize(cmd_line, prefs, machine_state);
  installer_state->set_target_path(target_dir);
  EXPECT_TRUE(installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER)
      != NULL);
}

wchar_t text_content_1[] = L"delete me";
wchar_t text_content_2[] = L"delete me as well";

// Delete version directories. Everything lower than the given version
// should be deleted.
TEST_F(InstallerStateTest, Delete) {
  // TODO(grt): move common stuff into the test fixture.
  // Create a Chrome dir
  base::FilePath chrome_dir(test_dir_.path());
  chrome_dir = chrome_dir.AppendASCII("chrome");
  base::CreateDirectory(chrome_dir);
  ASSERT_TRUE(base::PathExists(chrome_dir));

  base::FilePath chrome_dir_1(chrome_dir);
  chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
  base::CreateDirectory(chrome_dir_1);
  ASSERT_TRUE(base::PathExists(chrome_dir_1));

  base::FilePath chrome_dir_2(chrome_dir);
  chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
  base::CreateDirectory(chrome_dir_2);
  ASSERT_TRUE(base::PathExists(chrome_dir_2));

  base::FilePath chrome_dir_3(chrome_dir);
  chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
  base::CreateDirectory(chrome_dir_3);
  ASSERT_TRUE(base::PathExists(chrome_dir_3));

  base::FilePath chrome_dir_4(chrome_dir);
  chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
  base::CreateDirectory(chrome_dir_4);
  ASSERT_TRUE(base::PathExists(chrome_dir_4));

  base::FilePath chrome_dll_1(chrome_dir_1);
  chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_1.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_1));

  base::FilePath chrome_dll_2(chrome_dir_2);
  chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_2.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_2));

  base::FilePath chrome_dll_3(chrome_dir_3);
  chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_3.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_3));

  base::FilePath chrome_dll_4(chrome_dir_4);
  chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_4.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_4));

  MockInstallerState installer_state;
  BuildSingleChromeState(chrome_dir, &installer_state);
  Version latest_version("1.0.4.0");
  {
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    installer_state.RemoveOldVersionDirectories(latest_version, NULL,
                                                temp_dir.path());
  }

  // old versions should be gone
  EXPECT_FALSE(base::PathExists(chrome_dir_1));
  EXPECT_FALSE(base::PathExists(chrome_dir_2));
  EXPECT_FALSE(base::PathExists(chrome_dir_3));
  // the latest version should stay
  EXPECT_TRUE(base::PathExists(chrome_dll_4));
}

// Delete older version directories, keeping the one in used intact.
TEST_F(InstallerStateTest, DeleteInUsed) {
  // Create a Chrome dir
  base::FilePath chrome_dir(test_dir_.path());
  chrome_dir = chrome_dir.AppendASCII("chrome");
  base::CreateDirectory(chrome_dir);
  ASSERT_TRUE(base::PathExists(chrome_dir));

  base::FilePath chrome_dir_1(chrome_dir);
  chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
  base::CreateDirectory(chrome_dir_1);
  ASSERT_TRUE(base::PathExists(chrome_dir_1));

  base::FilePath chrome_dir_2(chrome_dir);
  chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
  base::CreateDirectory(chrome_dir_2);
  ASSERT_TRUE(base::PathExists(chrome_dir_2));

  base::FilePath chrome_dir_3(chrome_dir);
  chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
  base::CreateDirectory(chrome_dir_3);
  ASSERT_TRUE(base::PathExists(chrome_dir_3));

  base::FilePath chrome_dir_4(chrome_dir);
  chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
  base::CreateDirectory(chrome_dir_4);
  ASSERT_TRUE(base::PathExists(chrome_dir_4));

  base::FilePath chrome_dll_1(chrome_dir_1);
  chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_1.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_1));

  base::FilePath chrome_dll_2(chrome_dir_2);
  chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_2.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_2));

  // Open the file to make it in use.
  std::ofstream file;
  file.open(chrome_dll_2.value().c_str());

  base::FilePath chrome_othera_2(chrome_dir_2);
  chrome_othera_2 = chrome_othera_2.AppendASCII("othera.dll");
  CreateTextFile(chrome_othera_2.value(), text_content_2);
  ASSERT_TRUE(base::PathExists(chrome_othera_2));

  base::FilePath chrome_otherb_2(chrome_dir_2);
  chrome_otherb_2 = chrome_otherb_2.AppendASCII("otherb.dll");
  CreateTextFile(chrome_otherb_2.value(), text_content_2);
  ASSERT_TRUE(base::PathExists(chrome_otherb_2));

  base::FilePath chrome_dll_3(chrome_dir_3);
  chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_3.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_3));

  base::FilePath chrome_dll_4(chrome_dir_4);
  chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
  CreateTextFile(chrome_dll_4.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(chrome_dll_4));

  MockInstallerState installer_state;
  BuildSingleChromeState(chrome_dir, &installer_state);
  Version latest_version("1.0.4.0");
  Version existing_version("1.0.1.0");
  {
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    installer_state.RemoveOldVersionDirectories(latest_version,
                                                &existing_version,
                                                temp_dir.path());
  }

  // the version defined as the existing version should stay
  EXPECT_TRUE(base::PathExists(chrome_dir_1));
  // old versions not in used should be gone
  EXPECT_FALSE(base::PathExists(chrome_dir_3));
  // every thing under in used version should stay
  EXPECT_TRUE(base::PathExists(chrome_dir_2));
  EXPECT_TRUE(base::PathExists(chrome_dll_2));
  EXPECT_TRUE(base::PathExists(chrome_othera_2));
  EXPECT_TRUE(base::PathExists(chrome_otherb_2));
  // the latest version should stay
  EXPECT_TRUE(base::PathExists(chrome_dll_4));
}

// Tests a few basic things of the Package class.  Makes sure that the path
// operations are correct
TEST_F(InstallerStateTest, Basic) {
  const bool multi_install = false;
  const bool system_level = true;
  CommandLine cmd_line = CommandLine::FromString(
      std::wstring(L"setup.exe") +
      (multi_install ? L" --multi-install --chrome" : L"") +
      (system_level ? L" --system-level" : L""));
  MasterPreferences prefs(cmd_line);
  InstallationState machine_state;
  machine_state.Initialize();
  MockInstallerState installer_state;
  installer_state.Initialize(cmd_line, prefs, machine_state);
  installer_state.set_target_path(test_dir_.path());
  EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());
  EXPECT_EQ(1U, installer_state.products().size());

  const char kOldVersion[] = "1.2.3.4";
  const char kNewVersion[] = "2.3.4.5";

  Version new_version(kNewVersion);
  Version old_version(kOldVersion);
  ASSERT_TRUE(new_version.IsValid());
  ASSERT_TRUE(old_version.IsValid());

  base::FilePath installer_dir(
      installer_state.GetInstallerDirectory(new_version));
  EXPECT_FALSE(installer_dir.empty());

  base::FilePath new_version_dir(installer_state.target_path().Append(
      base::UTF8ToWide(new_version.GetString())));
  base::FilePath old_version_dir(installer_state.target_path().Append(
      base::UTF8ToWide(old_version.GetString())));

  EXPECT_FALSE(base::PathExists(new_version_dir));
  EXPECT_FALSE(base::PathExists(old_version_dir));

  EXPECT_FALSE(base::PathExists(installer_dir));
  base::CreateDirectory(installer_dir);
  EXPECT_TRUE(base::PathExists(new_version_dir));

  base::CreateDirectory(old_version_dir);
  EXPECT_TRUE(base::PathExists(old_version_dir));

  // Create a fake chrome.dll key file in the old version directory.  This
  // should prevent the old version directory from getting deleted.
  base::FilePath old_chrome_dll(old_version_dir.Append(installer::kChromeDll));
  EXPECT_FALSE(base::PathExists(old_chrome_dll));

  // Hold on to the file exclusively to prevent the directory from
  // being deleted.
  base::win::ScopedHandle file(
    ::CreateFile(old_chrome_dll.value().c_str(), GENERIC_READ,
                 0, NULL, OPEN_ALWAYS, 0, NULL));
  EXPECT_TRUE(file.IsValid());
  EXPECT_TRUE(base::PathExists(old_chrome_dll));

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Don't explicitly tell the directory cleanup logic not to delete the
  // old version, rely on the key files to keep it around.
  installer_state.RemoveOldVersionDirectories(new_version,
                                              NULL,
                                              temp_dir.path());

  // The old directory should still exist.
  EXPECT_TRUE(base::PathExists(old_version_dir));
  EXPECT_TRUE(base::PathExists(new_version_dir));

  // Now close the file handle to make it possible to delete our key file.
  file.Close();

  installer_state.RemoveOldVersionDirectories(new_version,
                                              NULL,
                                              temp_dir.path());
  // The new directory should still exist.
  EXPECT_TRUE(base::PathExists(new_version_dir));

  // Now, the old directory and key file should be gone.
  EXPECT_FALSE(base::PathExists(old_chrome_dll));
  EXPECT_FALSE(base::PathExists(old_version_dir));
}

TEST_F(InstallerStateTest, WithProduct) {
  const bool multi_install = false;
  const bool system_level = true;
  CommandLine cmd_line = CommandLine::FromString(
      std::wstring(L"setup.exe") +
      (multi_install ? L" --multi-install --chrome" : L"") +
      (system_level ? L" --system-level" : L""));
  MasterPreferences prefs(cmd_line);
  InstallationState machine_state;
  machine_state.Initialize();
  MockInstallerState installer_state;
  installer_state.Initialize(cmd_line, prefs, machine_state);
  installer_state.set_target_path(test_dir_.path());
  EXPECT_EQ(1U, installer_state.products().size());
  EXPECT_EQ(system_level, installer_state.system_install());

  const char kCurrentVersion[] = "1.2.3.4";
  Version current_version(kCurrentVersion);

  HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
  EXPECT_EQ(root, installer_state.root_key());

  {
    RegistryOverrideManager override_manager;
    override_manager.OverrideRegistry(root, L"root_pit");
    BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
        BrowserDistribution::CHROME_BROWSER);
    RegKey chrome_key(root, dist->GetVersionKey().c_str(), KEY_ALL_ACCESS);
    EXPECT_TRUE(chrome_key.Valid());
    if (chrome_key.Valid()) {
      chrome_key.WriteValue(google_update::kRegVersionField,
                            base::UTF8ToWide(
                                current_version.GetString()).c_str());
      machine_state.Initialize();
      // TODO(tommi): Also test for when there exists a new_chrome.exe.
      Version found_version(*installer_state.GetCurrentVersion(machine_state));
      EXPECT_TRUE(found_version.IsValid());
      if (found_version.IsValid())
        EXPECT_TRUE(current_version.Equals(found_version));
    }
  }
}

TEST_F(InstallerStateTest, InstallerResult) {
  const bool system_level = true;
  bool multi_install = false;
  HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;

  RegKey key;
  std::wstring launch_cmd = L"hey diddle diddle";
  std::wstring value;
  DWORD dw_value;

  // check results for a fresh install of single Chrome
  {
    RegistryOverrideManager override_manager;
    override_manager.OverrideRegistry(root, L"root_inst_res");
    CommandLine cmd_line = CommandLine::FromString(L"setup.exe --system-level");
    const MasterPreferences prefs(cmd_line);
    InstallationState machine_state;
    machine_state.Initialize();
    InstallerState state;
    state.Initialize(cmd_line, prefs, machine_state);
    state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS,
                               IDS_INSTALL_OS_ERROR_BASE, &launch_cmd);
    BrowserDistribution* distribution =
        BrowserDistribution::GetSpecificDistribution(
            BrowserDistribution::CHROME_BROWSER);
    EXPECT_EQ(ERROR_SUCCESS,
        key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
    EXPECT_EQ(ERROR_SUCCESS,
        key.ReadValueDW(installer::kInstallerResult, &dw_value));
    EXPECT_EQ(static_cast<DWORD>(0), dw_value);
    EXPECT_EQ(ERROR_SUCCESS,
        key.ReadValueDW(installer::kInstallerError, &dw_value));
    EXPECT_EQ(static_cast<DWORD>(installer::FIRST_INSTALL_SUCCESS), dw_value);
    EXPECT_EQ(ERROR_SUCCESS,
        key.ReadValue(installer::kInstallerResultUIString, &value));
    EXPECT_FALSE(value.empty());
    EXPECT_EQ(ERROR_SUCCESS,
        key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
    EXPECT_EQ(launch_cmd, value);
  }

  // check results for a fresh install of multi Chrome
  {
    RegistryOverrideManager override_manager;
    override_manager.OverrideRegistry(root, L"root_inst_res");
    CommandLine cmd_line = CommandLine::FromString(
        L"setup.exe --system-level --multi-install --chrome");
    const MasterPreferences prefs(cmd_line);
    InstallationState machine_state;
    machine_state.Initialize();
    InstallerState state;
    state.Initialize(cmd_line, prefs, machine_state);
    state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS, 0,
                               &launch_cmd);
    BrowserDistribution* distribution =
        BrowserDistribution::GetSpecificDistribution(
            BrowserDistribution::CHROME_BROWSER);
    BrowserDistribution* binaries =
        BrowserDistribution::GetSpecificDistribution(
            BrowserDistribution::CHROME_BINARIES);
    EXPECT_EQ(ERROR_SUCCESS,
        key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
    EXPECT_EQ(ERROR_SUCCESS,
        key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
    EXPECT_EQ(launch_cmd, value);
    EXPECT_EQ(ERROR_SUCCESS,
        key.Open(root, binaries->GetStateKey().c_str(), KEY_READ));
    EXPECT_EQ(ERROR_SUCCESS,
        key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
    EXPECT_EQ(launch_cmd, value);
    key.Close();
  }
}

// Test GetCurrentVersion when migrating single Chrome to multi
TEST_F(InstallerStateTest, GetCurrentVersionMigrateChrome) {
  using installer::FakeInstallationState;

  const bool system_install = false;
  FakeInstallationState machine_state;

  // Pretend that this version of single-install Chrome is already installed.
  machine_state.AddChrome(system_install, false,
                          new Version(chrome::kChromeVersion));

  // Now we're invoked to install multi Chrome.
  CommandLine cmd_line(
      CommandLine::FromString(L"setup.exe --multi-install --chrome"));
  MasterPreferences prefs(cmd_line);
  InstallerState installer_state;
  installer_state.Initialize(cmd_line, prefs, machine_state);

  // Is the Chrome version picked up?
  scoped_ptr<Version> version(installer_state.GetCurrentVersion(machine_state));
  EXPECT_TRUE(version.get() != NULL);
}

TEST_F(InstallerStateTest, IsFileInUse) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  base::FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));

  EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));

  {
    // Open a handle to the file with the same access mode and sharing options
    // as the loader.
    base::win::ScopedHandle temp_handle(
        CreateFile(temp_file.value().c_str(),
                   SYNCHRONIZE | FILE_EXECUTE,
                   FILE_SHARE_DELETE | FILE_SHARE_READ,
                   NULL, OPEN_EXISTING, 0, 0));
    ASSERT_TRUE(temp_handle != NULL);

    // The file should now be in use.
    EXPECT_TRUE(MockInstallerState::IsFileInUse(temp_file));
  }

  // And once the handle is gone, it should no longer be in use.
  EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));
}

TEST_F(InstallerStateTest, RemoveOldVersionDirs) {
  MockInstallerState installer_state;
  installer_state.set_target_path(test_dir_.path());
  EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());

  const char kOldVersion[] = "2.0.0.0";
  const char kNewVersion[] = "3.0.0.0";
  const char kOldChromeExeVersion[] = "2.1.0.0";
  const char kChromeExeVersion[] = "2.1.1.1";
  const char kNewChromeExeVersion[] = "3.0.0.0";

  Version new_version(kNewVersion);
  Version old_version(kOldVersion);
  Version old_chrome_exe_version(kOldChromeExeVersion);
  Version chrome_exe_version(kChromeExeVersion);
  Version new_chrome_exe_version(kNewChromeExeVersion);

  ASSERT_TRUE(new_version.IsValid());
  ASSERT_TRUE(old_version.IsValid());
  ASSERT_TRUE(old_chrome_exe_version.IsValid());
  ASSERT_TRUE(chrome_exe_version.IsValid());
  ASSERT_TRUE(new_chrome_exe_version.IsValid());

  // Set up a bunch of version dir paths.
  base::FilePath version_dirs[] = {
    installer_state.target_path().Append(L"1.2.3.4"),
    installer_state.target_path().Append(L"1.2.3.5"),
    installer_state.target_path().Append(L"1.2.3.6"),
    installer_state.target_path().Append(base::ASCIIToWide(kOldVersion)),
    installer_state.target_path().Append(
        base::ASCIIToWide(kOldChromeExeVersion)),
    installer_state.target_path().Append(L"2.1.1.0"),
    installer_state.target_path().Append(base::ASCIIToWide(kChromeExeVersion)),
    installer_state.target_path().Append(base::ASCIIToWide(kNewVersion)),
    installer_state.target_path().Append(L"3.9.1.1"),
  };

  // Create the version directories.
  for (int i = 0; i < arraysize(version_dirs); i++) {
    base::CreateDirectory(version_dirs[i]);
    EXPECT_TRUE(base::PathExists(version_dirs[i]));
  }

  // Create exes with the appropriate version resource.
  // Use the current test exe as a baseline.
  base::FilePath exe_path;
  ASSERT_TRUE(PathService::Get(base::FILE_EXE, &exe_path));

  struct target_info {
    base::FilePath target_file;
    const Version& target_version;
  } targets[] = {
    { installer_state.target_path().Append(installer::kChromeOldExe),
      old_chrome_exe_version },
    { installer_state.target_path().Append(installer::kChromeExe),
      chrome_exe_version },
    { installer_state.target_path().Append(installer::kChromeNewExe),
      new_chrome_exe_version },
  };
  for (int i = 0; i < arraysize(targets); ++i) {
    ASSERT_TRUE(upgrade_test::GenerateSpecificPEFileVersion(
        exe_path, targets[i].target_file, targets[i].target_version));
  }

  // Call GetExistingExeVersions, validate that picks up the
  // exe resources.
  std::set<std::string> expected_exe_versions;
  expected_exe_versions.insert(kOldChromeExeVersion);
  expected_exe_versions.insert(kChromeExeVersion);
  expected_exe_versions.insert(kNewChromeExeVersion);

  std::set<std::string> actual_exe_versions;
  installer_state.GetExistingExeVersions(&actual_exe_versions);
  EXPECT_EQ(expected_exe_versions, actual_exe_versions);

  // Call RemoveOldVersionDirectories
  installer_state.RemoveOldVersionDirectories(new_version,
                                              &old_version,
                                              installer_state.target_path());

  // What we expect to have left.
  std::set<std::string> expected_remaining_dirs;
  expected_remaining_dirs.insert(kOldVersion);
  expected_remaining_dirs.insert(kNewVersion);
  expected_remaining_dirs.insert(kOldChromeExeVersion);
  expected_remaining_dirs.insert(kChromeExeVersion);
  expected_remaining_dirs.insert(kNewChromeExeVersion);

  // Enumerate dirs in target_path(), ensure only desired remain.
  base::FileEnumerator version_enum(installer_state.target_path(), false,
                                    base::FileEnumerator::DIRECTORIES);
  for (base::FilePath next_version = version_enum.Next(); !next_version.empty();
       next_version = version_enum.Next()) {
    base::FilePath dir_name(next_version.BaseName());
    Version version(base::UTF16ToASCII(dir_name.value()));
    if (version.IsValid()) {
      EXPECT_TRUE(expected_remaining_dirs.erase(version.GetString()))
          << "Unexpected version dir found: " << version.GetString();
    }
  }

  std::set<std::string>::const_iterator iter(
      expected_remaining_dirs.begin());
  for (; iter != expected_remaining_dirs.end(); ++iter)
    ADD_FAILURE() << "Expected to find version dir for " << *iter;
}

TEST_F(InstallerStateTest, InitializeTwice) {
  InstallationState machine_state;
  machine_state.Initialize();

  InstallerState installer_state;

  // Initialize the instance to install multi Chrome.
  {
    CommandLine cmd_line(
        CommandLine::FromString(L"setup.exe --multi-install --chrome"));
    MasterPreferences prefs(cmd_line);
    installer_state.Initialize(cmd_line, prefs, machine_state);
  }
  // Confirm the expected state.
  EXPECT_EQ(InstallerState::USER_LEVEL, installer_state.level());
  EXPECT_EQ(InstallerState::MULTI_PACKAGE, installer_state.package_type());
  EXPECT_EQ(InstallerState::MULTI_INSTALL, installer_state.operation());
  EXPECT_TRUE(wcsstr(installer_state.target_path().value().c_str(),
                     BrowserDistribution::GetSpecificDistribution(
                         BrowserDistribution::CHROME_BINARIES)->
                         GetInstallSubDir().c_str()));
  EXPECT_FALSE(installer_state.verbose_logging());
  EXPECT_EQ(installer_state.state_key(),
            BrowserDistribution::GetSpecificDistribution(
                BrowserDistribution::CHROME_BROWSER)->GetStateKey());
  EXPECT_EQ(installer_state.state_type(), BrowserDistribution::CHROME_BROWSER);
  EXPECT_TRUE(installer_state.multi_package_binaries_distribution());
  EXPECT_TRUE(installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER));

  // Now initialize it to install system-level single Chrome.
  {
    CommandLine cmd_line(
        CommandLine::FromString(L"setup.exe --system-level --verbose-logging"));
    MasterPreferences prefs(cmd_line);
    installer_state.Initialize(cmd_line, prefs, machine_state);
  }

  // Confirm that the old state is gone.
  EXPECT_EQ(InstallerState::SYSTEM_LEVEL, installer_state.level());
  EXPECT_EQ(InstallerState::SINGLE_PACKAGE, installer_state.package_type());
  EXPECT_EQ(InstallerState::SINGLE_INSTALL_OR_UPDATE,
            installer_state.operation());
  EXPECT_TRUE(wcsstr(installer_state.target_path().value().c_str(),
                     BrowserDistribution::GetSpecificDistribution(
                         BrowserDistribution::CHROME_BROWSER)->
                         GetInstallSubDir().c_str()));
  EXPECT_TRUE(installer_state.verbose_logging());
  EXPECT_EQ(installer_state.state_key(),
            BrowserDistribution::GetSpecificDistribution(
                BrowserDistribution::CHROME_BROWSER)->GetStateKey());
  EXPECT_EQ(installer_state.state_type(), BrowserDistribution::CHROME_BROWSER);
  EXPECT_TRUE(installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER));
}

// A fixture for testing InstallerState::DetermineCriticalVersion.  Individual
// tests must invoke Initialize() with a critical version.
class InstallerStateCriticalVersionTest : public ::testing::Test {
 protected:
  InstallerStateCriticalVersionTest() : cmd_line_(CommandLine::NO_PROGRAM) {}

  // Creates a set of versions for use by all test runs.
  static void SetUpTestCase() {
    low_version_    = new Version("15.0.874.106");
    opv_version_    = new Version("15.0.874.255");
    middle_version_ = new Version("16.0.912.32");
    pv_version_     = new Version("16.0.912.255");
    high_version_   = new Version("17.0.932.0");
  }

  // Cleans up versions used by all test runs.
  static void TearDownTestCase() {
    delete low_version_;
    delete opv_version_;
    delete middle_version_;
    delete pv_version_;
    delete high_version_;
  }

  // Initializes the InstallerState to use for a test run.  The returned
  // instance's critical update version is set to |version|.  |version| may be
  // NULL, in which case the critical update version is unset.
  MockInstallerState& Initialize(const Version* version) {
    cmd_line_ = version == NULL ?
        CommandLine::FromString(L"setup.exe") :
        CommandLine::FromString(
            L"setup.exe --critical-update-version=" +
            base::ASCIIToWide(version->GetString()));
    prefs_.reset(new MasterPreferences(cmd_line_));
    machine_state_.Initialize();
    installer_state_.Initialize(cmd_line_, *prefs_, machine_state_);
    return installer_state_;
  }

  static Version* low_version_;
  static Version* opv_version_;
  static Version* middle_version_;
  static Version* pv_version_;
  static Version* high_version_;

  CommandLine cmd_line_;
  scoped_ptr<MasterPreferences> prefs_;
  InstallationState machine_state_;
  MockInstallerState installer_state_;
};

Version* InstallerStateCriticalVersionTest::low_version_ = NULL;
Version* InstallerStateCriticalVersionTest::opv_version_ = NULL;
Version* InstallerStateCriticalVersionTest::middle_version_ = NULL;
Version* InstallerStateCriticalVersionTest::pv_version_ = NULL;
Version* InstallerStateCriticalVersionTest::high_version_ = NULL;

// Test the case where the critical version is less than the currently-running
// Chrome.  The critical version is ignored since it doesn't apply.
TEST_F(InstallerStateCriticalVersionTest, CriticalBeforeOpv) {
  MockInstallerState& installer_state(Initialize(low_version_));

  EXPECT_TRUE(installer_state.critical_update_version().Equals(*low_version_));
  // Unable to determine the installed version, so assume critical update.
  EXPECT_TRUE(
      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
  // Installed version is past the critical update.
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
          .IsValid());
  // Installed version is past the critical update.
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
          .IsValid());
}

// Test the case where the critical version is equal to the currently-running
// Chrome.  The critical version is ignored since it doesn't apply.
TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsOpv) {
  MockInstallerState& installer_state(Initialize(opv_version_));

  EXPECT_TRUE(installer_state.critical_update_version().Equals(*opv_version_));
  // Unable to determine the installed version, so assume critical update.
  EXPECT_TRUE(
      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
  // Installed version equals the critical update.
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
          .IsValid());
  // Installed version equals the critical update.
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
          .IsValid());
}

// Test the case where the critical version is between the currently-running
// Chrome and the to-be-installed Chrome.
TEST_F(InstallerStateCriticalVersionTest, CriticalBetweenOpvAndPv) {
  MockInstallerState& installer_state(Initialize(middle_version_));

  EXPECT_TRUE(installer_state.critical_update_version().Equals(
      *middle_version_));
  // Unable to determine the installed version, so assume critical update.
  EXPECT_TRUE(
      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
  // Installed version before the critical update.
  EXPECT_TRUE(
      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
          .IsValid());
  // Installed version is past the critical update.
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
          .IsValid());
}

// Test the case where the critical version is the same as the to-be-installed
// Chrome.
TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsPv) {
  MockInstallerState& installer_state(Initialize(pv_version_));

  EXPECT_TRUE(installer_state.critical_update_version().Equals(
      *pv_version_));
  // Unable to determine the installed version, so assume critical update.
  EXPECT_TRUE(
      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
  // Installed version before the critical update.
  EXPECT_TRUE(
      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
          .IsValid());
  // Installed version equals the critical update.
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
          .IsValid());
}

// Test the case where the critical version is greater than the to-be-installed
// Chrome.
TEST_F(InstallerStateCriticalVersionTest, CriticalAfterPv) {
  MockInstallerState& installer_state(Initialize(high_version_));

  EXPECT_TRUE(installer_state.critical_update_version().Equals(
      *high_version_));
  // Critical update newer than the new version.
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
          .IsValid());
  EXPECT_FALSE(
      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
          .IsValid());
}
