| // 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. | 
 |  | 
 | // This file declares helper functions for use in tests that expect a valid | 
 | // installation, possibly of a specific type.  Validation violations result in | 
 | // test failures. | 
 |  | 
 | #include "chrome/installer/util/installation_validation_helper.h" | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include "base/logging.h" | 
 | #include "base/strings/string_piece.h" | 
 | #include "chrome/installer/util/installation_state.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 |  | 
 | namespace installer { | 
 |  | 
 | namespace { | 
 |  | 
 | // A helper class that installs a log message handler to add a test failure for | 
 | // each ERROR message.  Only one instance of this class may be live at a time. | 
 | class FailureLogHelper { | 
 |  public: | 
 |   FailureLogHelper(); | 
 |   ~FailureLogHelper(); | 
 |  | 
 |  private: | 
 |   static bool AddFailureForLogMessage(int severity, | 
 |                                       const char* file, | 
 |                                       int line, | 
 |                                       size_t message_start, | 
 |                                       const std::string& str); | 
 |  | 
 |   static const logging::LogSeverity kViolationSeverity_; | 
 |   static logging::LogMessageHandlerFunction old_message_handler_; | 
 |   static int old_min_log_level_; | 
 | }; | 
 |  | 
 | // InstallationValidator logs all violations at ERROR level. | 
 | // static | 
 | const logging::LogSeverity | 
 |     FailureLogHelper::kViolationSeverity_ = logging::LOG_ERROR; | 
 |  | 
 | // static | 
 | logging::LogMessageHandlerFunction | 
 |     FailureLogHelper::old_message_handler_ = NULL; | 
 |  | 
 | // static | 
 | int FailureLogHelper::old_min_log_level_ = | 
 |     FailureLogHelper::kViolationSeverity_; | 
 |  | 
 | FailureLogHelper::FailureLogHelper() { | 
 |   LOG_ASSERT(old_message_handler_ == NULL); | 
 |  | 
 |   // The validator logs at ERROR level.  Ensure that it generates messages so we | 
 |   // can transform them into test failures. | 
 |   old_min_log_level_ = logging::GetMinLogLevel(); | 
 |   if (old_min_log_level_ > kViolationSeverity_) | 
 |     logging::SetMinLogLevel(kViolationSeverity_); | 
 |  | 
 |   old_message_handler_ = logging::GetLogMessageHandler(); | 
 |   logging::SetLogMessageHandler(&AddFailureForLogMessage); | 
 | } | 
 |  | 
 | FailureLogHelper::~FailureLogHelper() { | 
 |   logging::SetLogMessageHandler(old_message_handler_); | 
 |   old_message_handler_ = NULL; | 
 |  | 
 |   if (old_min_log_level_ > kViolationSeverity_) | 
 |     logging::SetMinLogLevel(old_min_log_level_); | 
 | } | 
 |  | 
 | // A logging::LogMessageHandlerFunction that adds a non-fatal test failure | 
 | // (i.e., similar to an unmet EXPECT_FOO) for each non-empty message logged at | 
 | // the severity of validation violations.  All other messages are sent through | 
 | // the default logging pipeline. | 
 | // static | 
 | bool FailureLogHelper::AddFailureForLogMessage(int severity, | 
 |                                                const char* file, | 
 |                                                int line, | 
 |                                                size_t message_start, | 
 |                                                const std::string& str) { | 
 |   if (severity == kViolationSeverity_ && !str.empty()) { | 
 |     // Remove the trailing newline, if present. | 
 |     size_t message_length = str.size() - message_start; | 
 |     if (*str.rbegin() == '\n') | 
 |       --message_length; | 
 |     ADD_FAILURE_AT(file, line) | 
 |         << base::StringPiece(str.c_str() + message_start, message_length); | 
 |     return true; | 
 |   } | 
 |  | 
 |   if (old_message_handler_ != NULL) | 
 |     return (old_message_handler_)(severity, file, line, message_start, str); | 
 |  | 
 |   return false; | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | InstallationValidator::InstallationType ExpectValidInstallation( | 
 |     bool system_level) { | 
 |   FailureLogHelper log_helper; | 
 |   InstallationValidator::InstallationType found_type = | 
 |       InstallationValidator::NO_PRODUCTS; | 
 |  | 
 |   EXPECT_TRUE(InstallationValidator::ValidateInstallationType(system_level, | 
 |                                                               &found_type)); | 
 |   return found_type; | 
 | } | 
 |  | 
 | InstallationValidator::InstallationType ExpectValidInstallationForState( | 
 |     const InstallationState& machine_state, | 
 |     bool system_level) { | 
 |   FailureLogHelper log_helper; | 
 |   InstallationValidator::InstallationType found_type = | 
 |       InstallationValidator::NO_PRODUCTS; | 
 |  | 
 |   EXPECT_TRUE(InstallationValidator::ValidateInstallationTypeForState( | 
 |       machine_state, system_level, &found_type)); | 
 |   return found_type; | 
 | } | 
 |  | 
 | void ExpectInstallationOfType(bool system_level, | 
 |                               InstallationValidator::InstallationType type) { | 
 |   EXPECT_EQ(type, ExpectValidInstallation(system_level)); | 
 | } | 
 |  | 
 | void ExpectInstallationOfTypeForState( | 
 |     const InstallationState& machine_state, | 
 |     bool system_level, | 
 |     InstallationValidator::InstallationType type) { | 
 |   EXPECT_EQ(type, ExpectValidInstallationForState(machine_state, system_level)); | 
 | } | 
 |  | 
 | }  // namespace installer |