root/chrome/installer/util/product_state_unittest.cc

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

DEFINITIONS

This source file includes following definitions.
  1. SetUpTestCase
  2. TearDownTestCase
  3. SetUp
  4. TearDown
  5. MinimallyInstallProduct
  6. ApplyUninstallCommand
  7. TEST_F
  8. TEST_F
  9. TEST_F
  10. TEST_F
  11. TEST_F
  12. TEST_F
  13. TEST_F

// Copyright (c) 2011 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 "base/strings/utf_string_conversions.h"
#include "base/test/test_reg_util_win.h"
#include "base/version.h"
#include "base/win/registry.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/installation_state.h"
#include "chrome/installer/util/product_unittest.h"
#include "chrome/installer/util/util_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::win::RegKey;
using installer::ProductState;
using registry_util::RegistryOverrideManager;

class ProductStateTest : public testing::Test {
 protected:
  static void SetUpTestCase();
  static void TearDownTestCase();

  virtual void SetUp();
  virtual void TearDown();

  void ApplyUninstallCommand(const wchar_t* exe_path, const wchar_t* args);
  void MinimallyInstallProduct(const wchar_t* version);

  static BrowserDistribution* dist_;
  bool system_install_;
  HKEY overridden_;
  registry_util::RegistryOverrideManager registry_override_manager_;
  RegKey clients_;
  RegKey client_state_;
};

BrowserDistribution* ProductStateTest::dist_;

// static
void ProductStateTest::SetUpTestCase() {
  testing::Test::SetUpTestCase();

  // We'll use Chrome as our test subject.
  dist_ = BrowserDistribution::GetSpecificDistribution(
      BrowserDistribution::CHROME_BROWSER);
}

// static
void ProductStateTest::TearDownTestCase() {
  dist_ = NULL;

  testing::Test::TearDownTestCase();
}

void ProductStateTest::SetUp() {
  testing::Test::SetUp();

  // Create/open the keys for the product we'll test.
  system_install_ = true;
  overridden_ = (system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);

  // Override for test purposes.  We don't use ScopedRegistryKeyOverride
  // directly because it doesn't suit itself to our use here.
  RegKey temp_key;

  registry_override_manager_.OverrideRegistry(overridden_, L"ProductStateTest");

  EXPECT_EQ(ERROR_SUCCESS,
            clients_.Create(overridden_, dist_->GetVersionKey().c_str(),
                            KEY_ALL_ACCESS));
  EXPECT_EQ(ERROR_SUCCESS,
            client_state_.Create(overridden_, dist_->GetStateKey().c_str(),
                                 KEY_ALL_ACCESS));
}

void ProductStateTest::TearDown() {
  // Done with the keys.
  client_state_.Close();
  clients_.Close();
  overridden_ = NULL;
  system_install_ = false;

  testing::Test::TearDown();
}

void ProductStateTest::MinimallyInstallProduct(const wchar_t* version) {
  EXPECT_EQ(ERROR_SUCCESS,
            clients_.WriteValue(google_update::kRegVersionField, version));
}

void ProductStateTest::ApplyUninstallCommand(const wchar_t* exe_path,
                                             const wchar_t* args) {
  if (exe_path == NULL) {
    LONG result = client_state_.DeleteValue(installer::kUninstallStringField);
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
  } else {
    EXPECT_EQ(ERROR_SUCCESS,
              client_state_.WriteValue(installer::kUninstallStringField,
                                       exe_path));
  }

  if (args == NULL) {
    LONG result =
        client_state_.DeleteValue(installer::kUninstallArgumentsField);
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
  } else {
    EXPECT_EQ(ERROR_SUCCESS,
              client_state_.WriteValue(installer::kUninstallArgumentsField,
                                       args));
  }
}

TEST_F(ProductStateTest, InitializeInstalled) {
  // Not installed.
  {
    ProductState state;
    LONG result = clients_.DeleteValue(google_update::kRegVersionField);
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_FALSE(state.Initialize(system_install_, dist_));
  }

  // Empty version.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegVersionField, L"");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_FALSE(state.Initialize(system_install_, dist_));
  }

  // Bogus version.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegVersionField,
                                      L"goofy");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_FALSE(state.Initialize(system_install_, dist_));
  }

  // Valid "pv" value.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegVersionField,
                                      L"10.0.47.0");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_EQ("10.0.47.0", state.version().GetString());
  }
}

// Test extraction of the "opv" value from the Clients key.
TEST_F(ProductStateTest, InitializeOldVersion) {
  MinimallyInstallProduct(L"10.0.1.1");

  // No "opv" value.
  {
    ProductState state;
    LONG result = clients_.DeleteValue(google_update::kRegOldVersionField);
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.old_version() == NULL);
  }

  // Empty "opv" value.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegOldVersionField, L"");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.old_version() == NULL);
  }

  // Bogus "opv" value.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegOldVersionField,
                                      L"coming home");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.old_version() == NULL);
  }

  // Valid "opv" value.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegOldVersionField,
                                      L"10.0.47.0");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.old_version() != NULL);
    EXPECT_EQ("10.0.47.0", state.old_version()->GetString());
  }
}

// Test extraction of the "cmd" value from the Clients key.
TEST_F(ProductStateTest, InitializeRenameCmd) {
  MinimallyInstallProduct(L"10.0.1.1");

  // No "cmd" value.
  {
    ProductState state;
    LONG result = clients_.DeleteValue(google_update::kRegRenameCmdField);
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.rename_cmd().empty());
  }

  // Empty "cmd" value.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegRenameCmdField, L"");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.rename_cmd().empty());
  }

  // Valid "cmd" value.
  {
    ProductState state;
    LONG result = clients_.WriteValue(google_update::kRegRenameCmdField,
                                      L"spam.exe --spamalot");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_EQ(L"spam.exe --spamalot", state.rename_cmd());
  }
}

// Test extraction of the "ap" value from the ClientState key.
TEST_F(ProductStateTest, InitializeChannelInfo) {
  MinimallyInstallProduct(L"10.0.1.1");

  // No "ap" value.
  {
    ProductState state;
    LONG result = client_state_.DeleteValue(google_update::kRegApField);
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.channel().value().empty());
  }

  // Empty "ap" value.
  {
    ProductState state;
    LONG result = client_state_.WriteValue(google_update::kRegApField, L"");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.channel().value().empty());
  }

  // Valid "ap" value.
  {
    ProductState state;
    LONG result = client_state_.WriteValue(google_update::kRegApField, L"spam");
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_EQ(L"spam", state.channel().value());
  }
}

// Test extraction of the uninstall command and arguments from the ClientState
// key.
TEST_F(ProductStateTest, InitializeUninstallCommand) {
  MinimallyInstallProduct(L"10.0.1.1");

  // No uninstall command.
  {
    ProductState state;
    ApplyUninstallCommand(NULL, NULL);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.GetSetupPath().empty());
    EXPECT_TRUE(state.uninstall_command().GetCommandLineString().empty());
    EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
  }

  // Empty values.
  {
    ProductState state;
    ApplyUninstallCommand(L"", L"");
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.GetSetupPath().empty());
    EXPECT_TRUE(state.uninstall_command().GetCommandLineString().empty());
    EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
  }

  // Uninstall command without exe.
  {
    ProductState state;
    ApplyUninstallCommand(NULL, L"--uninstall");
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.GetSetupPath().empty());
    EXPECT_EQ(L" --uninstall",
              state.uninstall_command().GetCommandLineString());
    EXPECT_EQ(1U, state.uninstall_command().GetSwitches().size());
  }

  // Uninstall command without args.
  {
    ProductState state;
    ApplyUninstallCommand(L"setup.exe", NULL);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_EQ(L"setup.exe", state.GetSetupPath().value());
    EXPECT_EQ(L"setup.exe", state.uninstall_command().GetCommandLineString());
    EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
  }

  // Uninstall command with exe that requires quoting.
  {
    ProductState state;
    ApplyUninstallCommand(L"set up.exe", NULL);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_EQ(L"set up.exe", state.GetSetupPath().value());
    EXPECT_EQ(L"\"set up.exe\"",
              state.uninstall_command().GetCommandLineString());
    EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
  }

  // Uninstall command with both exe and args.
  {
    ProductState state;
    ApplyUninstallCommand(L"setup.exe", L"--uninstall");
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_EQ(L"setup.exe", state.GetSetupPath().value());
    EXPECT_EQ(L"setup.exe --uninstall",
              state.uninstall_command().GetCommandLineString());
    EXPECT_EQ(1U, state.uninstall_command().GetSwitches().size());
  }
}

// Test extraction of the msi marker from the ClientState key.
TEST_F(ProductStateTest, InitializeMsi) {
  MinimallyInstallProduct(L"10.0.1.1");

  // No msi marker.
  {
    ProductState state;
    LONG result = client_state_.DeleteValue(google_update::kRegMSIField);
    EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_FALSE(state.is_msi());
  }

  // Msi marker set to zero.
  {
    ProductState state;
    EXPECT_EQ(ERROR_SUCCESS,
              client_state_.WriteValue(google_update::kRegMSIField,
                                       static_cast<DWORD>(0)));
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_FALSE(state.is_msi());
  }

  // Msi marker set to one.
  {
    ProductState state;
    EXPECT_EQ(ERROR_SUCCESS,
              client_state_.WriteValue(google_update::kRegMSIField,
                                       static_cast<DWORD>(1)));
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.is_msi());
  }

  // Msi marker set to a bogus DWORD.
  {
    ProductState state;
    EXPECT_EQ(ERROR_SUCCESS,
              client_state_.WriteValue(google_update::kRegMSIField,
                                       static_cast<DWORD>(47)));
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.is_msi());
  }

  // Msi marker set to a bogus string.
  {
    ProductState state;
    EXPECT_EQ(ERROR_SUCCESS,
              client_state_.WriteValue(google_update::kRegMSIField,
                                       L"bogus!"));
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_FALSE(state.is_msi());
  }
}

// Test detection of multi-install.
TEST_F(ProductStateTest, InitializeMultiInstall) {
  MinimallyInstallProduct(L"10.0.1.1");

  // No uninstall command means single install.
  {
    ProductState state;
    ApplyUninstallCommand(NULL, NULL);
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_FALSE(state.is_multi_install());
  }

  // Uninstall command without --multi-install is single install.
  {
    ProductState state;
    ApplyUninstallCommand(L"setup.exe", L"--uninstall");
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_FALSE(state.is_multi_install());
  }

  // Uninstall command with --multi-install is multi install.
  {
    ProductState state;
    ApplyUninstallCommand(L"setup.exe",
                          L"--uninstall --chrome --multi-install");
    EXPECT_TRUE(state.Initialize(system_install_, dist_));
    EXPECT_TRUE(state.is_multi_install());
  }
}

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