Home | History | Annotate | Download | only in util
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <windows.h>
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "base/test/test_reg_util_win.h"
      9 #include "base/version.h"
     10 #include "base/win/registry.h"
     11 #include "chrome/installer/util/browser_distribution.h"
     12 #include "chrome/installer/util/google_update_constants.h"
     13 #include "chrome/installer/util/installation_state.h"
     14 #include "chrome/installer/util/product_unittest.h"
     15 #include "chrome/installer/util/util_constants.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 using base::win::RegKey;
     19 using installer::ProductState;
     20 using registry_util::RegistryOverrideManager;
     21 
     22 class ProductStateTest : public testing::Test {
     23  protected:
     24   static void SetUpTestCase();
     25   static void TearDownTestCase();
     26 
     27   virtual void SetUp();
     28   virtual void TearDown();
     29 
     30   void ApplyUninstallCommand(const wchar_t* exe_path, const wchar_t* args);
     31   void MinimallyInstallProduct(const wchar_t* version);
     32 
     33   static BrowserDistribution* dist_;
     34   bool system_install_;
     35   HKEY overridden_;
     36   registry_util::RegistryOverrideManager registry_override_manager_;
     37   RegKey clients_;
     38   RegKey client_state_;
     39 };
     40 
     41 BrowserDistribution* ProductStateTest::dist_;
     42 
     43 // static
     44 void ProductStateTest::SetUpTestCase() {
     45   testing::Test::SetUpTestCase();
     46 
     47   // We'll use Chrome as our test subject.
     48   dist_ = BrowserDistribution::GetSpecificDistribution(
     49       BrowserDistribution::CHROME_BROWSER);
     50 }
     51 
     52 // static
     53 void ProductStateTest::TearDownTestCase() {
     54   dist_ = NULL;
     55 
     56   testing::Test::TearDownTestCase();
     57 }
     58 
     59 void ProductStateTest::SetUp() {
     60   testing::Test::SetUp();
     61 
     62   // Create/open the keys for the product we'll test.
     63   system_install_ = true;
     64   overridden_ = (system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);
     65 
     66   // Override for test purposes.  We don't use ScopedRegistryKeyOverride
     67   // directly because it doesn't suit itself to our use here.
     68   RegKey temp_key;
     69 
     70   registry_override_manager_.OverrideRegistry(overridden_, L"ProductStateTest");
     71 
     72   EXPECT_EQ(ERROR_SUCCESS,
     73             clients_.Create(overridden_, dist_->GetVersionKey().c_str(),
     74                             KEY_ALL_ACCESS));
     75   EXPECT_EQ(ERROR_SUCCESS,
     76             client_state_.Create(overridden_, dist_->GetStateKey().c_str(),
     77                                  KEY_ALL_ACCESS));
     78 }
     79 
     80 void ProductStateTest::TearDown() {
     81   // Done with the keys.
     82   client_state_.Close();
     83   clients_.Close();
     84   overridden_ = NULL;
     85   system_install_ = false;
     86 
     87   testing::Test::TearDown();
     88 }
     89 
     90 void ProductStateTest::MinimallyInstallProduct(const wchar_t* version) {
     91   EXPECT_EQ(ERROR_SUCCESS,
     92             clients_.WriteValue(google_update::kRegVersionField, version));
     93 }
     94 
     95 void ProductStateTest::ApplyUninstallCommand(const wchar_t* exe_path,
     96                                              const wchar_t* args) {
     97   if (exe_path == NULL) {
     98     LONG result = client_state_.DeleteValue(installer::kUninstallStringField);
     99     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    100   } else {
    101     EXPECT_EQ(ERROR_SUCCESS,
    102               client_state_.WriteValue(installer::kUninstallStringField,
    103                                        exe_path));
    104   }
    105 
    106   if (args == NULL) {
    107     LONG result =
    108         client_state_.DeleteValue(installer::kUninstallArgumentsField);
    109     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    110   } else {
    111     EXPECT_EQ(ERROR_SUCCESS,
    112               client_state_.WriteValue(installer::kUninstallArgumentsField,
    113                                        args));
    114   }
    115 }
    116 
    117 TEST_F(ProductStateTest, InitializeInstalled) {
    118   // Not installed.
    119   {
    120     ProductState state;
    121     LONG result = clients_.DeleteValue(google_update::kRegVersionField);
    122     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    123     EXPECT_FALSE(state.Initialize(system_install_, dist_));
    124   }
    125 
    126   // Empty version.
    127   {
    128     ProductState state;
    129     LONG result = clients_.WriteValue(google_update::kRegVersionField, L"");
    130     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    131     EXPECT_FALSE(state.Initialize(system_install_, dist_));
    132   }
    133 
    134   // Bogus version.
    135   {
    136     ProductState state;
    137     LONG result = clients_.WriteValue(google_update::kRegVersionField,
    138                                       L"goofy");
    139     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    140     EXPECT_FALSE(state.Initialize(system_install_, dist_));
    141   }
    142 
    143   // Valid "pv" value.
    144   {
    145     ProductState state;
    146     LONG result = clients_.WriteValue(google_update::kRegVersionField,
    147                                       L"10.0.47.0");
    148     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    149     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    150     EXPECT_EQ("10.0.47.0", state.version().GetString());
    151   }
    152 }
    153 
    154 // Test extraction of the "opv" value from the Clients key.
    155 TEST_F(ProductStateTest, InitializeOldVersion) {
    156   MinimallyInstallProduct(L"10.0.1.1");
    157 
    158   // No "opv" value.
    159   {
    160     ProductState state;
    161     LONG result = clients_.DeleteValue(google_update::kRegOldVersionField);
    162     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    163     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    164     EXPECT_TRUE(state.old_version() == NULL);
    165   }
    166 
    167   // Empty "opv" value.
    168   {
    169     ProductState state;
    170     LONG result = clients_.WriteValue(google_update::kRegOldVersionField, L"");
    171     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    172     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    173     EXPECT_TRUE(state.old_version() == NULL);
    174   }
    175 
    176   // Bogus "opv" value.
    177   {
    178     ProductState state;
    179     LONG result = clients_.WriteValue(google_update::kRegOldVersionField,
    180                                       L"coming home");
    181     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    182     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    183     EXPECT_TRUE(state.old_version() == NULL);
    184   }
    185 
    186   // Valid "opv" value.
    187   {
    188     ProductState state;
    189     LONG result = clients_.WriteValue(google_update::kRegOldVersionField,
    190                                       L"10.0.47.0");
    191     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    192     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    193     EXPECT_TRUE(state.old_version() != NULL);
    194     EXPECT_EQ("10.0.47.0", state.old_version()->GetString());
    195   }
    196 }
    197 
    198 // Test extraction of the "cmd" value from the Clients key.
    199 TEST_F(ProductStateTest, InitializeRenameCmd) {
    200   MinimallyInstallProduct(L"10.0.1.1");
    201 
    202   // No "cmd" value.
    203   {
    204     ProductState state;
    205     LONG result = clients_.DeleteValue(google_update::kRegRenameCmdField);
    206     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    207     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    208     EXPECT_TRUE(state.rename_cmd().empty());
    209   }
    210 
    211   // Empty "cmd" value.
    212   {
    213     ProductState state;
    214     LONG result = clients_.WriteValue(google_update::kRegRenameCmdField, L"");
    215     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    216     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    217     EXPECT_TRUE(state.rename_cmd().empty());
    218   }
    219 
    220   // Valid "cmd" value.
    221   {
    222     ProductState state;
    223     LONG result = clients_.WriteValue(google_update::kRegRenameCmdField,
    224                                       L"spam.exe --spamalot");
    225     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    226     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    227     EXPECT_EQ(L"spam.exe --spamalot", state.rename_cmd());
    228   }
    229 }
    230 
    231 // Test extraction of the "ap" value from the ClientState key.
    232 TEST_F(ProductStateTest, InitializeChannelInfo) {
    233   MinimallyInstallProduct(L"10.0.1.1");
    234 
    235   // No "ap" value.
    236   {
    237     ProductState state;
    238     LONG result = client_state_.DeleteValue(google_update::kRegApField);
    239     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    240     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    241     EXPECT_TRUE(state.channel().value().empty());
    242   }
    243 
    244   // Empty "ap" value.
    245   {
    246     ProductState state;
    247     LONG result = client_state_.WriteValue(google_update::kRegApField, L"");
    248     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    249     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    250     EXPECT_TRUE(state.channel().value().empty());
    251   }
    252 
    253   // Valid "ap" value.
    254   {
    255     ProductState state;
    256     LONG result = client_state_.WriteValue(google_update::kRegApField, L"spam");
    257     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    258     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    259     EXPECT_EQ(L"spam", state.channel().value());
    260   }
    261 }
    262 
    263 // Test extraction of the uninstall command and arguments from the ClientState
    264 // key.
    265 TEST_F(ProductStateTest, InitializeUninstallCommand) {
    266   MinimallyInstallProduct(L"10.0.1.1");
    267 
    268   // No uninstall command.
    269   {
    270     ProductState state;
    271     ApplyUninstallCommand(NULL, NULL);
    272     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    273     EXPECT_TRUE(state.GetSetupPath().empty());
    274     EXPECT_TRUE(state.uninstall_command().GetCommandLineString().empty());
    275     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
    276   }
    277 
    278   // Empty values.
    279   {
    280     ProductState state;
    281     ApplyUninstallCommand(L"", L"");
    282     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    283     EXPECT_TRUE(state.GetSetupPath().empty());
    284     EXPECT_TRUE(state.uninstall_command().GetCommandLineString().empty());
    285     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
    286   }
    287 
    288   // Uninstall command without exe.
    289   {
    290     ProductState state;
    291     ApplyUninstallCommand(NULL, L"--uninstall");
    292     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    293     EXPECT_TRUE(state.GetSetupPath().empty());
    294     EXPECT_EQ(L" --uninstall",
    295               state.uninstall_command().GetCommandLineString());
    296     EXPECT_EQ(1U, state.uninstall_command().GetSwitches().size());
    297   }
    298 
    299   // Uninstall command without args.
    300   {
    301     ProductState state;
    302     ApplyUninstallCommand(L"setup.exe", NULL);
    303     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    304     EXPECT_EQ(L"setup.exe", state.GetSetupPath().value());
    305     EXPECT_EQ(L"setup.exe", state.uninstall_command().GetCommandLineString());
    306     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
    307   }
    308 
    309   // Uninstall command with exe that requires quoting.
    310   {
    311     ProductState state;
    312     ApplyUninstallCommand(L"set up.exe", NULL);
    313     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    314     EXPECT_EQ(L"set up.exe", state.GetSetupPath().value());
    315     EXPECT_EQ(L"\"set up.exe\"",
    316               state.uninstall_command().GetCommandLineString());
    317     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
    318   }
    319 
    320   // Uninstall command with both exe and args.
    321   {
    322     ProductState state;
    323     ApplyUninstallCommand(L"setup.exe", L"--uninstall");
    324     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    325     EXPECT_EQ(L"setup.exe", state.GetSetupPath().value());
    326     EXPECT_EQ(L"setup.exe --uninstall",
    327               state.uninstall_command().GetCommandLineString());
    328     EXPECT_EQ(1U, state.uninstall_command().GetSwitches().size());
    329   }
    330 }
    331 
    332 // Test extraction of the msi marker from the ClientState key.
    333 TEST_F(ProductStateTest, InitializeMsi) {
    334   MinimallyInstallProduct(L"10.0.1.1");
    335 
    336   // No msi marker.
    337   {
    338     ProductState state;
    339     LONG result = client_state_.DeleteValue(google_update::kRegMSIField);
    340     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
    341     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    342     EXPECT_FALSE(state.is_msi());
    343   }
    344 
    345   // Msi marker set to zero.
    346   {
    347     ProductState state;
    348     EXPECT_EQ(ERROR_SUCCESS,
    349               client_state_.WriteValue(google_update::kRegMSIField,
    350                                        static_cast<DWORD>(0)));
    351     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    352     EXPECT_FALSE(state.is_msi());
    353   }
    354 
    355   // Msi marker set to one.
    356   {
    357     ProductState state;
    358     EXPECT_EQ(ERROR_SUCCESS,
    359               client_state_.WriteValue(google_update::kRegMSIField,
    360                                        static_cast<DWORD>(1)));
    361     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    362     EXPECT_TRUE(state.is_msi());
    363   }
    364 
    365   // Msi marker set to a bogus DWORD.
    366   {
    367     ProductState state;
    368     EXPECT_EQ(ERROR_SUCCESS,
    369               client_state_.WriteValue(google_update::kRegMSIField,
    370                                        static_cast<DWORD>(47)));
    371     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    372     EXPECT_TRUE(state.is_msi());
    373   }
    374 
    375   // Msi marker set to a bogus string.
    376   {
    377     ProductState state;
    378     EXPECT_EQ(ERROR_SUCCESS,
    379               client_state_.WriteValue(google_update::kRegMSIField,
    380                                        L"bogus!"));
    381     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    382     EXPECT_FALSE(state.is_msi());
    383   }
    384 }
    385 
    386 // Test detection of multi-install.
    387 TEST_F(ProductStateTest, InitializeMultiInstall) {
    388   MinimallyInstallProduct(L"10.0.1.1");
    389 
    390   // No uninstall command means single install.
    391   {
    392     ProductState state;
    393     ApplyUninstallCommand(NULL, NULL);
    394     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    395     EXPECT_FALSE(state.is_multi_install());
    396   }
    397 
    398   // Uninstall command without --multi-install is single install.
    399   {
    400     ProductState state;
    401     ApplyUninstallCommand(L"setup.exe", L"--uninstall");
    402     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    403     EXPECT_FALSE(state.is_multi_install());
    404   }
    405 
    406   // Uninstall command with --multi-install is multi install.
    407   {
    408     ProductState state;
    409     ApplyUninstallCommand(L"setup.exe",
    410                           L"--uninstall --chrome --multi-install");
    411     EXPECT_TRUE(state.Initialize(system_install_, dist_));
    412     EXPECT_TRUE(state.is_multi_install());
    413   }
    414 }
    415