Home | History | Annotate | Download | only in util
      1 // Copyright (c) 2012 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 <map>
      6 
      7 #include "base/command_line.h"
      8 #include "base/files/file_path.h"
      9 #include "base/logging.h"
     10 #include "base/memory/ref_counted.h"
     11 #include "base/version.h"
     12 #include "chrome/common/chrome_constants.h"
     13 #include "chrome/common/chrome_switches.h"
     14 #include "chrome/installer/util/channel_info.h"
     15 #include "chrome/installer/util/helper.h"
     16 #include "chrome/installer/util/installation_state.h"
     17 #include "chrome/installer/util/installation_validator.h"
     18 #include "testing/gmock/include/gmock/gmock.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 using installer::ChannelInfo;
     22 using installer::InstallationValidator;
     23 using installer::InstallationState;
     24 using installer::AppCommand;
     25 using installer::ProductState;
     26 using testing::_;
     27 using testing::StrictMock;
     28 using testing::Values;
     29 
     30 namespace {
     31 
     32 enum Channel {
     33   STABLE_CHANNEL,
     34   BETA_CHANNEL,
     35   DEV_CHANNEL
     36 };
     37 
     38 enum PackageType {
     39   SINGLE_INSTALL,
     40   MULTI_INSTALL
     41 };
     42 
     43 enum Level {
     44   USER_LEVEL,
     45   SYSTEM_LEVEL
     46 };
     47 
     48 enum Vehicle {
     49   GOOGLE_UPDATE,
     50   MSI
     51 };
     52 
     53 enum ChannelModifier {
     54   CM_MULTI        = 0x01,
     55   CM_CHROME       = 0x02,
     56   CM_CHROME_FRAME = 0x04,
     57   CM_READY_MODE   = 0x08,
     58   CM_FULL         = 0x10
     59 };
     60 
     61 const wchar_t* const kChromeChannels[] = {
     62   L"",
     63   L"1.1-beta",
     64   L"2.0-dev"
     65 };
     66 
     67 const wchar_t* const kChromeFrameChannels[] = {
     68   L"",
     69   L"beta",
     70   L"dev"
     71 };
     72 
     73 class FakeProductState : public ProductState {
     74  public:
     75   void SetChannel(const wchar_t* base, int channel_modifiers);
     76   void SetVersion(const char* version);
     77   void SetUninstallCommand(BrowserDistribution::Type dist_type,
     78                            Level install_level,
     79                            const char* version,
     80                            int channel_modifiers,
     81                            Vehicle vehicle);
     82   void AddInstallExtensionCommand(BrowserDistribution::Type dist_type,
     83                                   Level install_level,
     84                                   const char* version,
     85                                   int channel_modifiers);
     86   void AddOsUpgradeCommand(BrowserDistribution::Type dist_type,
     87                            Level install_level,
     88                            const char* version,
     89                            int channel_modifiers);
     90   void AddQueryEULAAcceptanceCommand(BrowserDistribution::Type dist_type,
     91                                      Level install_level,
     92                                      const char* version,
     93                                      int channel_modifiers);
     94   void AddQuickEnableApplicationHostCommand(BrowserDistribution::Type dist_type,
     95                                             Level install_level,
     96                                             const char* version,
     97                                             int channel_modifiers);
     98   void AddQuickEnableCfCommand(BrowserDistribution::Type dist_type,
     99                                Level install_level,
    100                                const char* version,
    101                                int channel_modifiers);
    102   void set_multi_install(bool is_multi_install) {
    103     multi_install_ = is_multi_install;
    104   }
    105   installer::AppCommands& commands() { return commands_; }
    106 
    107  protected:
    108   struct ChannelMethodForModifier {
    109     ChannelModifier modifier;
    110     bool (ChannelInfo::*method)(bool value);
    111   };
    112 
    113   static base::FilePath GetSetupPath(
    114       BrowserDistribution::Type dist_type,
    115       Level install_level,
    116       int channel_modifiers);
    117 
    118   static base::FilePath GetSetupExePath(
    119       BrowserDistribution::Type dist_type,
    120       Level install_level,
    121       const char* version,
    122       int channel_modifiers);
    123 
    124   static const ChannelMethodForModifier kChannelMethods[];
    125 };
    126 
    127 class FakeInstallationState : public InstallationState {
    128  public:
    129   void SetProductState(BrowserDistribution::Type type,
    130                        Level install_level,
    131                        const ProductState& product) {
    132     GetProducts(install_level)[IndexFromDistType(type)].CopyFrom(product);
    133   }
    134 
    135  protected:
    136   ProductState* GetProducts(Level install_level) {
    137     return install_level == USER_LEVEL ? user_products_ : system_products_;
    138   }
    139 };
    140 
    141 // static
    142 const FakeProductState::ChannelMethodForModifier
    143     FakeProductState::kChannelMethods[] = {
    144   { CM_MULTI,        &ChannelInfo::SetMultiInstall },
    145   { CM_CHROME,       &ChannelInfo::SetChrome },
    146   { CM_CHROME_FRAME, &ChannelInfo::SetChromeFrame },
    147   { CM_READY_MODE,   &ChannelInfo::SetReadyMode },
    148   { CM_FULL,         &ChannelInfo::SetFullSuffix }
    149 };
    150 
    151 // static
    152 base::FilePath FakeProductState::GetSetupPath(
    153     BrowserDistribution::Type dist_type,
    154     Level install_level,
    155     int channel_modifiers) {
    156   const bool is_multi_install = (channel_modifiers & CM_MULTI) != 0;
    157   return installer::GetChromeInstallPath(
    158       install_level == SYSTEM_LEVEL,
    159       BrowserDistribution::GetSpecificDistribution(is_multi_install ?
    160               BrowserDistribution::CHROME_BINARIES : dist_type));
    161 }
    162 
    163 // static
    164 base::FilePath FakeProductState::GetSetupExePath(
    165     BrowserDistribution::Type dist_type,
    166     Level install_level,
    167     const char* version,
    168     int channel_modifiers) {
    169   base::FilePath setup_path = GetSetupPath(dist_type, install_level,
    170                                            channel_modifiers);
    171   return setup_path
    172       .AppendASCII(version)
    173       .Append(installer::kInstallerDir)
    174       .Append(installer::kSetupExe);
    175 }
    176 
    177 // Sets the channel_ member of this instance according to a base channel value
    178 // and a set of modifiers.
    179 void FakeProductState::SetChannel(const wchar_t* base, int channel_modifiers) {
    180   channel_.set_value(base);
    181   for (size_t i = 0; i < arraysize(kChannelMethods); ++i) {
    182     if ((channel_modifiers & kChannelMethods[i].modifier) != 0)
    183       (channel_.*kChannelMethods[i].method)(true);
    184   }
    185 }
    186 
    187 void FakeProductState::SetVersion(const char* version) {
    188   version_.reset(version == NULL ? NULL : new Version(version));
    189 }
    190 
    191 // Sets the uninstall command for this object.
    192 void FakeProductState::SetUninstallCommand(BrowserDistribution::Type dist_type,
    193                                            Level install_level,
    194                                            const char* version,
    195                                            int channel_modifiers,
    196                                            Vehicle vehicle) {
    197   DCHECK(version);
    198 
    199   const bool is_multi_install = (channel_modifiers & CM_MULTI) != 0;
    200   uninstall_command_ = CommandLine(GetSetupExePath(dist_type, install_level,
    201                                                    version, channel_modifiers));
    202   uninstall_command_.AppendSwitch(installer::switches::kUninstall);
    203   if (install_level == SYSTEM_LEVEL)
    204     uninstall_command_.AppendSwitch(installer::switches::kSystemLevel);
    205   if (is_multi_install) {
    206     uninstall_command_.AppendSwitch(installer::switches::kMultiInstall);
    207     if (dist_type == BrowserDistribution::CHROME_BROWSER) {
    208       uninstall_command_.AppendSwitch(installer::switches::kChrome);
    209       if ((channel_modifiers & CM_READY_MODE) != 0) {
    210         uninstall_command_.AppendSwitch(installer::switches::kChromeFrame);
    211         uninstall_command_.AppendSwitch(
    212             installer::switches::kChromeFrameReadyMode);
    213       }
    214     } else if (dist_type == BrowserDistribution::CHROME_FRAME) {
    215       uninstall_command_.AppendSwitch(installer::switches::kChromeFrame);
    216       if ((channel_modifiers & CM_READY_MODE) != 0) {
    217         uninstall_command_.AppendSwitch(
    218             installer::switches::kChromeFrameReadyMode);
    219       }
    220     }
    221   } else if (dist_type == BrowserDistribution::CHROME_FRAME) {
    222     uninstall_command_.AppendSwitch(installer::switches::kChromeFrame);
    223   }
    224   if (vehicle == MSI)
    225     uninstall_command_.AppendSwitch(installer::switches::kMsi);
    226 }
    227 
    228 // Adds the "install-extension" Google Update product command.
    229 void FakeProductState::AddInstallExtensionCommand(
    230     BrowserDistribution::Type dist_type,
    231     Level install_level,
    232     const char* version,
    233     int channel_modifiers) {
    234   // Right now only Chrome browser uses this.
    235   DCHECK_EQ(dist_type, BrowserDistribution::CHROME_BROWSER);
    236 
    237   CommandLine cmd_line(GetSetupPath(dist_type, install_level,
    238                                     channel_modifiers).
    239                            Append(installer::kChromeExe));
    240   cmd_line.AppendSwitchASCII(::switches::kLimitedInstallFromWebstore, "%1");
    241   AppCommand app_cmd(cmd_line.GetCommandLineString());
    242   app_cmd.set_sends_pings(true);
    243   app_cmd.set_is_web_accessible(true);
    244   app_cmd.set_is_run_as_user(true);
    245   commands_.Set(installer::kCmdInstallExtension, app_cmd);
    246 }
    247 
    248 // Adds the "on-os-upgrade" Google Update product command.
    249 void FakeProductState::AddOsUpgradeCommand(BrowserDistribution::Type dist_type,
    250                                            Level install_level,
    251                                            const char* version,
    252                                            int channel_modifiers) {
    253   // Right now only Chrome browser uses this.
    254   DCHECK_EQ(dist_type, BrowserDistribution::CHROME_BROWSER);
    255 
    256   CommandLine cmd_line(GetSetupExePath(dist_type, install_level, version,
    257                                        channel_modifiers));
    258   cmd_line.AppendSwitch(installer::switches::kOnOsUpgrade);
    259   // Imitating ChromeBrowserOperations::AppendProductFlags().
    260   if ((channel_modifiers & CM_MULTI) != 0) {
    261     cmd_line.AppendSwitch(installer::switches::kMultiInstall);
    262     cmd_line.AppendSwitch(installer::switches::kChrome);
    263   }
    264   if (install_level == SYSTEM_LEVEL)
    265     cmd_line.AppendSwitch(installer::switches::kSystemLevel);
    266   cmd_line.AppendSwitch(installer::switches::kVerboseLogging);
    267   AppCommand app_cmd(cmd_line.GetCommandLineString());
    268   app_cmd.set_is_auto_run_on_os_upgrade(true);
    269   commands_.Set(installer::kCmdOnOsUpgrade, app_cmd);
    270 }
    271 
    272 // Adds the "query-eula-acceptance" Google Update product command.
    273 void FakeProductState::AddQueryEULAAcceptanceCommand(
    274     BrowserDistribution::Type dist_type,
    275     Level install_level,
    276     const char* version,
    277     int channel_modifiers) {
    278   DCHECK_EQ(dist_type, BrowserDistribution::CHROME_BINARIES);
    279 
    280   CommandLine cmd_line(GetSetupExePath(dist_type, install_level, version,
    281                                        channel_modifiers));
    282   cmd_line.AppendSwitch(installer::switches::kQueryEULAAcceptance);
    283   if (install_level == SYSTEM_LEVEL)
    284     cmd_line.AppendSwitch(installer::switches::kSystemLevel);
    285   cmd_line.AppendSwitch(installer::switches::kVerboseLogging);
    286   AppCommand app_cmd(cmd_line.GetCommandLineString());
    287   app_cmd.set_is_web_accessible(true);
    288   app_cmd.set_is_run_as_user(true);
    289   commands_.Set(installer::kCmdQueryEULAAcceptance, app_cmd);
    290 }
    291 
    292 // Adds the "quick-enable-application-host" Google Update product command.
    293 void FakeProductState::AddQuickEnableApplicationHostCommand(
    294     BrowserDistribution::Type dist_type,
    295     Level install_level,
    296     const char* version,
    297     int channel_modifiers) {
    298   DCHECK_EQ(dist_type, BrowserDistribution::CHROME_BINARIES);
    299   DCHECK_NE(channel_modifiers & CM_MULTI, 0);
    300 
    301   CommandLine cmd_line(GetSetupExePath(dist_type, install_level, version,
    302                                        channel_modifiers));
    303   cmd_line.AppendSwitch(installer::switches::kMultiInstall);
    304   cmd_line.AppendSwitch(installer::switches::kChromeAppLauncher);
    305   cmd_line.AppendSwitch(installer::switches::kEnsureGoogleUpdatePresent);
    306   AppCommand app_cmd(cmd_line.GetCommandLineString());
    307   app_cmd.set_sends_pings(true);
    308   app_cmd.set_is_web_accessible(true);
    309   app_cmd.set_is_run_as_user(true);
    310   commands_.Set(installer::kCmdQuickEnableApplicationHost, app_cmd);
    311 }
    312 
    313 // Adds the "quick-enable-cf" Google Update product command.
    314 void FakeProductState::AddQuickEnableCfCommand(
    315     BrowserDistribution::Type dist_type,
    316     Level install_level,
    317     const char* version,
    318     int channel_modifiers) {
    319   DCHECK_EQ(dist_type, BrowserDistribution::CHROME_BINARIES);
    320   DCHECK_NE(channel_modifiers & CM_MULTI, 0);
    321 
    322   CommandLine cmd_line(GetSetupExePath(dist_type, install_level, version,
    323                                        channel_modifiers));
    324   cmd_line.AppendSwitch(installer::switches::kMultiInstall);
    325   if (install_level == SYSTEM_LEVEL)
    326     cmd_line.AppendSwitch(installer::switches::kSystemLevel);
    327   cmd_line.AppendSwitch(installer::switches::kChromeFrameQuickEnable);
    328   AppCommand app_cmd(cmd_line.GetCommandLineString());
    329   app_cmd.set_sends_pings(true);
    330   app_cmd.set_is_web_accessible(true);
    331   commands_.Set(installer::kCmdQuickEnableCf, app_cmd);
    332 }
    333 
    334 }  // namespace
    335 
    336 // Fixture for testing the InstallationValidator.  Errors logged by the
    337 // validator are sent to an optional mock recipient (see
    338 // set_validation_error_recipient) upon which expectations can be placed.
    339 class InstallationValidatorTest
    340     : public testing::TestWithParam<InstallationValidator::InstallationType> {
    341  public:
    342 
    343   // These shouldn't need to be public, but there seems to be some interaction
    344   // with parameterized tests that requires it.
    345   static void SetUpTestCase();
    346   static void TearDownTestCase();
    347 
    348   // Returns the multi channel modifiers for a given installation type.
    349   static int GetChannelModifiers(InstallationValidator::InstallationType type);
    350 
    351  protected:
    352   typedef std::map<InstallationValidator::InstallationType, int>
    353       InstallationTypeToModifiers;
    354 
    355   class ValidationErrorRecipient {
    356    public:
    357     virtual ~ValidationErrorRecipient() { }
    358     virtual void ReceiveValidationError(const char* file,
    359                                         int line,
    360                                         const char* message) = 0;
    361   };
    362   class MockValidationErrorRecipient : public ValidationErrorRecipient {
    363    public:
    364     MOCK_METHOD3(ReceiveValidationError, void(const char* file,
    365                                               int line,
    366                                               const char* message));
    367   };
    368 
    369  protected:
    370   static bool HandleLogMessage(int severity,
    371                                const char* file,
    372                                int line,
    373                                size_t message_start,
    374                                const std::string& str);
    375   static void set_validation_error_recipient(
    376       ValidationErrorRecipient* recipient);
    377   static void MakeProductState(
    378       BrowserDistribution::Type prod_type,
    379       InstallationValidator::InstallationType inst_type,
    380       Level install_level,
    381       Channel channel,
    382       Vehicle vehicle,
    383       FakeProductState* state);
    384   static void MakeMachineState(
    385       InstallationValidator::InstallationType inst_type,
    386       Level install_level,
    387       Channel channel,
    388       Vehicle vehicle,
    389       FakeInstallationState* state);
    390   virtual void TearDown();
    391 
    392   static logging::LogMessageHandlerFunction old_log_message_handler_;
    393   static ValidationErrorRecipient* validation_error_recipient_;
    394   static InstallationTypeToModifiers* type_to_modifiers_;
    395 };
    396 
    397 // static
    398 logging::LogMessageHandlerFunction
    399     InstallationValidatorTest::old_log_message_handler_ = NULL;
    400 
    401 // static
    402 InstallationValidatorTest::ValidationErrorRecipient*
    403     InstallationValidatorTest::validation_error_recipient_ = NULL;
    404 
    405 // static
    406 InstallationValidatorTest::InstallationTypeToModifiers*
    407     InstallationValidatorTest::type_to_modifiers_ = NULL;
    408 
    409 // static
    410 int InstallationValidatorTest::GetChannelModifiers(
    411     InstallationValidator::InstallationType type) {
    412   DCHECK(type_to_modifiers_);
    413   DCHECK(type_to_modifiers_->find(type) != type_to_modifiers_->end());
    414 
    415   return (*type_to_modifiers_)[type];
    416 }
    417 
    418 // static
    419 void InstallationValidatorTest::SetUpTestCase() {
    420   DCHECK(type_to_modifiers_ == NULL);
    421   old_log_message_handler_ = logging::GetLogMessageHandler();
    422   logging::SetLogMessageHandler(&HandleLogMessage);
    423 
    424   type_to_modifiers_ = new InstallationTypeToModifiers();
    425   InstallationTypeToModifiers& ttm = *type_to_modifiers_;
    426   ttm[InstallationValidator::NO_PRODUCTS] = 0;
    427   ttm[InstallationValidator::CHROME_SINGLE] = 0;
    428   ttm[InstallationValidator::CHROME_MULTI] = CM_MULTI | CM_CHROME;
    429   ttm[InstallationValidator::CHROME_FRAME_SINGLE] = 0;
    430   ttm[InstallationValidator::CHROME_FRAME_SINGLE_CHROME_SINGLE] = 0;
    431   ttm[InstallationValidator::CHROME_FRAME_SINGLE_CHROME_MULTI] =
    432       CM_MULTI | CM_CHROME;
    433   ttm[InstallationValidator::CHROME_FRAME_MULTI] = CM_MULTI | CM_CHROME_FRAME;
    434   ttm[InstallationValidator::CHROME_FRAME_MULTI_CHROME_MULTI] =
    435       CM_MULTI | CM_CHROME_FRAME | CM_CHROME;
    436   ttm[InstallationValidator::CHROME_FRAME_READY_MODE_CHROME_MULTI] =
    437       CM_MULTI | CM_CHROME_FRAME | CM_CHROME | CM_READY_MODE;
    438 }
    439 
    440 // static
    441 void InstallationValidatorTest::TearDownTestCase() {
    442   logging::SetLogMessageHandler(old_log_message_handler_);
    443   old_log_message_handler_ = NULL;
    444 
    445   delete type_to_modifiers_;
    446   type_to_modifiers_ = NULL;
    447 }
    448 
    449 // static
    450 bool InstallationValidatorTest::HandleLogMessage(int severity,
    451                                                  const char* file,
    452                                                  int line,
    453                                                  size_t message_start,
    454                                                  const std::string& str) {
    455   // All validation failures result in LOG(ERROR)
    456   if (severity == logging::LOG_ERROR && !str.empty()) {
    457     // Remove the trailing newline, if present.
    458     size_t message_length = str.size() - message_start;
    459     if (*str.rbegin() == '\n')
    460       --message_length;
    461     if (validation_error_recipient_ != NULL) {
    462       validation_error_recipient_->ReceiveValidationError(
    463           file, line, str.substr(message_start, message_length).c_str());
    464     } else {
    465       // Fail the test if an error wasn't handled.
    466       ADD_FAILURE_AT(file, line)
    467           << base::StringPiece(str.c_str() + message_start, message_length);
    468     }
    469     return true;
    470   }
    471 
    472   if (old_log_message_handler_ != NULL)
    473     return (old_log_message_handler_)(severity, file, line, message_start, str);
    474 
    475   return false;
    476 }
    477 
    478 // static
    479 void InstallationValidatorTest::set_validation_error_recipient(
    480     ValidationErrorRecipient* recipient) {
    481   validation_error_recipient_ = recipient;
    482 }
    483 
    484 // static
    485 // Populates |state| with the state of a valid installation of product
    486 // |prod_type|.  |inst_type| dictates properties of the installation
    487 // (multi-install, ready-mode, etc).
    488 void InstallationValidatorTest::MakeProductState(
    489     BrowserDistribution::Type prod_type,
    490     InstallationValidator::InstallationType inst_type,
    491     Level install_level,
    492     Channel channel,
    493     Vehicle vehicle,
    494     FakeProductState* state) {
    495   DCHECK(state);
    496 
    497   const bool is_multi_install =
    498       prod_type == BrowserDistribution::CHROME_BINARIES ||
    499       (prod_type == BrowserDistribution::CHROME_BROWSER &&
    500        (inst_type & InstallationValidator::ProductBits::CHROME_MULTI) != 0) ||
    501       (prod_type == BrowserDistribution::CHROME_FRAME &&
    502        (inst_type &
    503            (InstallationValidator::ProductBits::CHROME_FRAME_MULTI |
    504             InstallationValidator::ProductBits::CHROME_FRAME_READY_MODE)) != 0);
    505 
    506   const wchar_t* const* channels = &kChromeChannels[0];
    507   if (prod_type == BrowserDistribution::CHROME_FRAME && !is_multi_install)
    508     channels = &kChromeFrameChannels[0];  // SxS GCF has its own channel names.
    509   const int channel_modifiers =
    510       is_multi_install ? GetChannelModifiers(inst_type) : 0;
    511 
    512   state->Clear();
    513   state->SetChannel(channels[channel], channel_modifiers);
    514   state->SetVersion(chrome::kChromeVersion);
    515   state->SetUninstallCommand(prod_type, install_level, chrome::kChromeVersion,
    516                              channel_modifiers, vehicle);
    517   state->set_multi_install(is_multi_install);
    518   if (prod_type == BrowserDistribution::CHROME_BINARIES) {
    519     if (inst_type == InstallationValidator::CHROME_MULTI ||
    520          inst_type ==
    521              InstallationValidator::CHROME_FRAME_READY_MODE_CHROME_MULTI) {
    522       state->AddQuickEnableCfCommand(prod_type, install_level,
    523                                      chrome::kChromeVersion, channel_modifiers);
    524     }
    525     state->AddQueryEULAAcceptanceCommand(prod_type,
    526                                          install_level,
    527                                          chrome::kChromeVersion,
    528                                          channel_modifiers);
    529   }
    530   if (prod_type == BrowserDistribution::CHROME_BINARIES) {
    531     state->AddQuickEnableApplicationHostCommand(prod_type,
    532                                                 install_level,
    533                                                 chrome::kChromeVersion,
    534                                                 channel_modifiers);
    535   }
    536   if (prod_type == BrowserDistribution::CHROME_BROWSER) {
    537     state->AddOsUpgradeCommand(prod_type,
    538                                install_level,
    539                                chrome::kChromeVersion,
    540                                channel_modifiers);
    541     state->AddInstallExtensionCommand(prod_type,
    542                                       install_level,
    543                                       chrome::kChromeVersion,
    544                                       channel_modifiers);
    545   }
    546 }
    547 
    548 // static
    549 // Populates |state| with the state of a valid installation of |inst_type|.
    550 void InstallationValidatorTest::MakeMachineState(
    551     InstallationValidator::InstallationType inst_type,
    552     Level install_level,
    553     Channel channel,
    554     Vehicle vehicle,
    555     FakeInstallationState* state) {
    556   DCHECK(state);
    557 
    558   static const int kChromeMask =
    559       (InstallationValidator::ProductBits::CHROME_SINGLE |
    560        InstallationValidator::ProductBits::CHROME_MULTI);
    561   static const int kChromeFrameMask =
    562       (InstallationValidator::ProductBits::CHROME_FRAME_SINGLE |
    563        InstallationValidator::ProductBits::CHROME_FRAME_MULTI |
    564        InstallationValidator::ProductBits::CHROME_FRAME_READY_MODE);
    565   static const int kBinariesMask =
    566       (InstallationValidator::ProductBits::CHROME_MULTI |
    567        InstallationValidator::ProductBits::CHROME_FRAME_MULTI |
    568        InstallationValidator::ProductBits::CHROME_FRAME_READY_MODE);
    569 
    570   FakeProductState prod_state;
    571 
    572   if ((inst_type & kChromeMask) != 0) {
    573     MakeProductState(BrowserDistribution::CHROME_BROWSER, inst_type,
    574                      install_level, channel, vehicle, &prod_state);
    575     state->SetProductState(BrowserDistribution::CHROME_BROWSER, install_level,
    576                            prod_state);
    577   }
    578 
    579   if ((inst_type & kChromeFrameMask) != 0) {
    580     MakeProductState(BrowserDistribution::CHROME_FRAME, inst_type,
    581                      install_level, channel, vehicle, &prod_state);
    582     state->SetProductState(BrowserDistribution::CHROME_FRAME, install_level,
    583                            prod_state);
    584   }
    585 
    586   if ((inst_type & kBinariesMask) != 0) {
    587     MakeProductState(BrowserDistribution::CHROME_BINARIES, inst_type,
    588                      install_level, channel, vehicle, &prod_state);
    589     state->SetProductState(BrowserDistribution::CHROME_BINARIES, install_level,
    590                            prod_state);
    591   }
    592 }
    593 
    594 void InstallationValidatorTest::TearDown() {
    595   validation_error_recipient_ = NULL;
    596 }
    597 
    598 // Builds a proper machine state for a given InstallationType, then validates
    599 // it.
    600 TEST_P(InstallationValidatorTest, TestValidInstallation) {
    601   const InstallationValidator::InstallationType inst_type = GetParam();
    602   FakeInstallationState machine_state;
    603   InstallationValidator::InstallationType type;
    604   StrictMock<MockValidationErrorRecipient> recipient;
    605   set_validation_error_recipient(&recipient);
    606 
    607   MakeMachineState(inst_type, SYSTEM_LEVEL, STABLE_CHANNEL, GOOGLE_UPDATE,
    608                    &machine_state);
    609   EXPECT_TRUE(InstallationValidator::ValidateInstallationTypeForState(
    610                   machine_state, true, &type));
    611   EXPECT_EQ(inst_type, type);
    612 }
    613 
    614 // Run the test for all installation types.
    615 INSTANTIATE_TEST_CASE_P(
    616     AllValidInstallations,
    617     InstallationValidatorTest,
    618     Values(InstallationValidator::NO_PRODUCTS,
    619            InstallationValidator::CHROME_SINGLE,
    620            InstallationValidator::CHROME_MULTI,
    621            InstallationValidator::CHROME_FRAME_SINGLE,
    622            InstallationValidator::CHROME_FRAME_SINGLE_CHROME_SINGLE,
    623            InstallationValidator::CHROME_FRAME_SINGLE_CHROME_MULTI,
    624            InstallationValidator::CHROME_FRAME_MULTI,
    625            InstallationValidator::CHROME_FRAME_MULTI_CHROME_MULTI,
    626            InstallationValidator::CHROME_FRAME_READY_MODE_CHROME_MULTI));
    627