This source file includes following definitions.
- OnTestProgramStart
- OnTestIterationStart
- OnEnvironmentsSetUpStart
- OnEnvironmentsSetUpEnd
- OnTestCaseStart
- OnTestStart
- OnTestPartResult
- OnTestEnd
- OnTestCaseEnd
- OnEnvironmentsTearDownStart
- OnEnvironmentsTearDownEnd
- OnTestIterationEnd
- OnTestProgramEnd
- default_result_printer_
- also_emit_success_logs_
- Initialize
- SetUp
- StartSessionForTest
- LogTestPartResult
- ProcessSessionForTest
- TearDown
- InstallTestLogCollector
#include "chrome/test/logging/win/test_log_collector.h"
#include <windows.h>
#include <algorithm>
#include <ios>
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
#include "chrome/test/base/test_switches.h"
#include "chrome/test/logging/win/file_logger.h"
#include "chrome/test/logging/win/log_file_printer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace logging_win {
namespace {
const char kTraceLogExtension[] = ".etl";
class TestLogCollector {
public:
TestLogCollector();
~TestLogCollector();
void Initialize(testing::UnitTest* unit_test);
void SetUp();
void StartSessionForTest(const testing::TestInfo& test_info);
bool LogTestPartResult(const testing::TestPartResult& test_part_result);
void ProcessSessionForTest(const testing::TestInfo& test_info);
void TearDown();
private:
class EventListener : public testing::TestEventListener {
public:
EventListener(TestLogCollector* test_log_collector,
testing::TestEventListener* default_result_printer);
virtual ~EventListener();
virtual void OnTestProgramStart(
const testing::UnitTest& unit_test) OVERRIDE {
test_log_collector_->SetUp();
default_result_printer_->OnTestProgramStart(unit_test);
}
virtual void OnTestIterationStart(const testing::UnitTest& unit_test,
int iteration) OVERRIDE {
default_result_printer_->OnTestIterationStart(unit_test, iteration);
}
virtual void OnEnvironmentsSetUpStart(
const testing::UnitTest& unit_test) OVERRIDE {
default_result_printer_->OnEnvironmentsSetUpStart(unit_test);
}
virtual void OnEnvironmentsSetUpEnd(
const testing::UnitTest& unit_test) OVERRIDE {
default_result_printer_->OnEnvironmentsSetUpEnd(unit_test);
}
virtual void OnTestCaseStart(const testing::TestCase& test_case) OVERRIDE {
default_result_printer_->OnTestCaseStart(test_case);
}
virtual void OnTestStart(const testing::TestInfo& test_info) OVERRIDE {
default_result_printer_->OnTestStart(test_info);
test_log_collector_->StartSessionForTest(test_info);
}
virtual void OnTestPartResult(
const testing::TestPartResult& test_part_result) OVERRIDE {
if (!test_log_collector_->LogTestPartResult(test_part_result))
default_result_printer_->OnTestPartResult(test_part_result);
}
virtual void OnTestEnd(const testing::TestInfo& test_info) OVERRIDE {
test_log_collector_->ProcessSessionForTest(test_info);
default_result_printer_->OnTestEnd(test_info);
}
virtual void OnTestCaseEnd(const testing::TestCase& test_case) OVERRIDE {
default_result_printer_->OnTestCaseEnd(test_case);
}
virtual void OnEnvironmentsTearDownStart(
const testing::UnitTest& unit_test) OVERRIDE {
default_result_printer_->OnEnvironmentsTearDownStart(unit_test);
}
virtual void OnEnvironmentsTearDownEnd(
const testing::UnitTest& unit_test) OVERRIDE {
default_result_printer_->OnEnvironmentsTearDownEnd(unit_test);
}
virtual void OnTestIterationEnd(const testing::UnitTest& unit_test,
int iteration) OVERRIDE {
default_result_printer_->OnTestIterationEnd(unit_test, iteration);
}
virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) OVERRIDE {
default_result_printer_->OnTestProgramEnd(unit_test);
test_log_collector_->TearDown();
}
private:
TestLogCollector* test_log_collector_;
scoped_ptr<testing::TestEventListener> default_result_printer_;
DISALLOW_COPY_AND_ASSIGN(EventListener);
};
testing::UnitTest* unit_test_;
base::ScopedTempDir log_temp_dir_;
scoped_ptr<FileLogger> file_logger_;
base::FilePath log_file_;
bool also_emit_success_logs_;
DISALLOW_COPY_AND_ASSIGN(TestLogCollector);
};
base::LazyInstance<TestLogCollector> g_test_log_collector =
LAZY_INSTANCE_INITIALIZER;
TestLogCollector::EventListener::EventListener(
TestLogCollector* test_log_collector,
testing::TestEventListener* default_result_printer)
: test_log_collector_(test_log_collector),
default_result_printer_(default_result_printer) {
}
TestLogCollector::EventListener::~EventListener() {
}
TestLogCollector::TestLogCollector()
: unit_test_(NULL), also_emit_success_logs_(false) {
}
TestLogCollector::~TestLogCollector() {
}
void TestLogCollector::Initialize(testing::UnitTest* unit_test) {
if (unit_test_ != NULL) {
CHECK_EQ(unit_test, unit_test_)
<< "Cannot install the test log collector in multiple unit tests.";
return;
}
testing::TestEventListeners& listeners = unit_test->listeners();
testing::TestEventListener* default_result_printer =
listeners.default_result_printer();
if (default_result_printer == NULL) {
LOG(ERROR) << "Failed to initialize the test log collector on account of "
"another component having released the default result "
"printer.";
} else {
listeners.Append(
new EventListener(this, listeners.Release(default_result_printer)));
also_emit_success_logs_ = CommandLine::ForCurrentProcess()->HasSwitch(
switches::kAlsoEmitSuccessLogs);
unit_test_ = unit_test;
}
}
void TestLogCollector::SetUp() {
if (!log_temp_dir_.CreateUniqueTempDir()) {
LOG(ERROR) << "Failed to create temporary directory to hold log files.";
} else {
file_logger_.reset(new FileLogger());
file_logger_->Initialize();
}
}
void TestLogCollector::StartSessionForTest(const testing::TestInfo& test_info) {
if (log_temp_dir_.IsValid()) {
std::string log_file_name(test_info.name());
std::replace(log_file_name.begin(), log_file_name.end(), '/', '_');
log_file_name.append(kTraceLogExtension);
log_file_ = log_temp_dir_.path().AppendASCII(log_file_name);
file_logger_->StartLogging(log_file_);
}
}
bool TestLogCollector::LogTestPartResult(
const testing::TestPartResult& test_part_result) {
if (!file_logger_.get() || !file_logger_->is_logging())
return false;
if (test_part_result.type() != testing::TestPartResult::kSuccess) {
LOG(ERROR)
<< base::StringPrintf("%s(%d): error: %s", test_part_result.file_name(),
test_part_result.line_number(),
test_part_result.message());
}
return true;
}
void TestLogCollector::ProcessSessionForTest(
const testing::TestInfo& test_info) {
if (file_logger_.get() != NULL && file_logger_->is_logging()) {
file_logger_->StopLogging();
if (also_emit_success_logs_ || test_info.result()->Failed()) {
std::cerr << "----- log messages for "
<< test_info.test_case_name() << "." << test_info.name()
<< " above this line are repeated below -----" << std::endl;
logging_win::PrintLogFile(log_file_, &std::cerr);
std::cerr.flush();
}
if (!base::DeleteFile(log_file_, false))
LOG(ERROR) << "Failed to delete log file " << log_file_.value();
}
log_file_.clear();
}
void TestLogCollector::TearDown() {
file_logger_.reset();
ignore_result(log_temp_dir_.Delete());
}
}
void InstallTestLogCollector(testing::UnitTest* unit_test) {
DCHECK(unit_test);
DCHECK(!unit_test->current_test_case());
g_test_log_collector.Get().Initialize(unit_test);
}
}