Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / test / logging / win / test_log_collector.cc
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 "chrome/test/logging/win/test_log_collector.h"
6
7 #include <windows.h>
8
9 #include <algorithm>
10 #include <ios>
11
12 #include "base/command_line.h"
13 #include "base/compiler_specific.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/files/scoped_temp_dir.h"
17 #include "base/lazy_instance.h"
18 #include "base/logging.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "base/strings/stringprintf.h"
21 #include "chrome/test/base/test_switches.h"
22 #include "chrome/test/logging/win/file_logger.h"
23 #include "chrome/test/logging/win/log_file_printer.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 namespace logging_win {
27
28 namespace {
29
30 const char kTraceLogExtension[] = ".etl";
31
32 class TestLogCollector {
33  public:
34   TestLogCollector();
35   ~TestLogCollector();
36
37   void Initialize(testing::UnitTest* unit_test);
38
39   void SetUp();
40   void StartSessionForTest(const testing::TestInfo& test_info);
41   bool LogTestPartResult(const testing::TestPartResult& test_part_result);
42   void ProcessSessionForTest(const testing::TestInfo& test_info);
43   void TearDown();
44
45  private:
46   // An EventListener that generally delegates to a given default result
47   // printer with a few exceptions; see individual method comments for details.
48   class EventListener : public testing::TestEventListener {
49    public:
50     // Ownership of |default_result_printer| is taken by the new instance.
51     EventListener(TestLogCollector* test_log_collector,
52                   testing::TestEventListener* default_result_printer);
53     virtual ~EventListener();
54
55     // Sets up the log collector.
56     virtual void OnTestProgramStart(
57         const testing::UnitTest& unit_test) override {
58       test_log_collector_->SetUp();
59       default_result_printer_->OnTestProgramStart(unit_test);
60     }
61
62     virtual void OnTestIterationStart(const testing::UnitTest& unit_test,
63                                       int iteration) override {
64       default_result_printer_->OnTestIterationStart(unit_test, iteration);
65     }
66
67     virtual void OnEnvironmentsSetUpStart(
68         const testing::UnitTest& unit_test) override {
69       default_result_printer_->OnEnvironmentsSetUpStart(unit_test);
70     }
71
72     virtual void OnEnvironmentsSetUpEnd(
73         const testing::UnitTest& unit_test) override {
74       default_result_printer_->OnEnvironmentsSetUpEnd(unit_test);
75     }
76
77     virtual void OnTestCaseStart(const testing::TestCase& test_case) override {
78       default_result_printer_->OnTestCaseStart(test_case);
79     }
80
81     // Calls back to the collector to start collecting logs for this test.
82     virtual void OnTestStart(const testing::TestInfo& test_info) override {
83       default_result_printer_->OnTestStart(test_info);
84       test_log_collector_->StartSessionForTest(test_info);
85     }
86
87     // Calls back to the collector with the partial result.  If the collector
88     // does not handle it, it is given to the default result printer.
89     virtual void OnTestPartResult(
90         const testing::TestPartResult& test_part_result) override {
91       if (!test_log_collector_->LogTestPartResult(test_part_result))
92         default_result_printer_->OnTestPartResult(test_part_result);
93     }
94
95     // Calls back to the collector to handle the collected log for the test that
96     // has just ended.
97     virtual void OnTestEnd(const testing::TestInfo& test_info) override {
98       test_log_collector_->ProcessSessionForTest(test_info);
99       default_result_printer_->OnTestEnd(test_info);
100     }
101
102     virtual void OnTestCaseEnd(const testing::TestCase& test_case) override {
103       default_result_printer_->OnTestCaseEnd(test_case);
104     }
105
106     virtual void OnEnvironmentsTearDownStart(
107         const testing::UnitTest& unit_test) override {
108       default_result_printer_->OnEnvironmentsTearDownStart(unit_test);
109     }
110
111     virtual void OnEnvironmentsTearDownEnd(
112         const testing::UnitTest& unit_test) override {
113       default_result_printer_->OnEnvironmentsTearDownEnd(unit_test);
114     }
115
116     virtual void OnTestIterationEnd(const testing::UnitTest& unit_test,
117                                     int iteration) override {
118       default_result_printer_->OnTestIterationEnd(unit_test, iteration);
119     }
120
121     // Tears down the log collector.
122     virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) override {
123       default_result_printer_->OnTestProgramEnd(unit_test);
124       test_log_collector_->TearDown();
125     }
126
127    private:
128     TestLogCollector* test_log_collector_;
129     scoped_ptr<testing::TestEventListener> default_result_printer_;
130
131     DISALLOW_COPY_AND_ASSIGN(EventListener);
132   };
133
134   // The Google Test unit test into which the collector has been installed.
135   testing::UnitTest* unit_test_;
136
137   // A temporary directory into which a log file is placed for the duration of
138   // each test.  Created/destroyed at collector SetUp and TearDown.
139   base::ScopedTempDir log_temp_dir_;
140
141   // The test logger.  Initialized/Unintitialized at collector SetUp and
142   // TearDown.
143   scoped_ptr<FileLogger> file_logger_;
144
145   // The current log file.  Valid only during a test.
146   base::FilePath log_file_;
147
148   // True if --also-emit-success-logs was specified on the command line.
149   bool also_emit_success_logs_;
150
151   DISALLOW_COPY_AND_ASSIGN(TestLogCollector);
152 };
153
154 base::LazyInstance<TestLogCollector> g_test_log_collector =
155     LAZY_INSTANCE_INITIALIZER;
156
157 // TestLogCollector::EventListener implementation
158
159 TestLogCollector::EventListener::EventListener(
160     TestLogCollector* test_log_collector,
161     testing::TestEventListener* default_result_printer)
162     : test_log_collector_(test_log_collector),
163       default_result_printer_(default_result_printer) {
164 }
165
166 TestLogCollector::EventListener::~EventListener() {
167 }
168
169 // TestLogCollector implementation
170
171 TestLogCollector::TestLogCollector()
172     : unit_test_(NULL), also_emit_success_logs_(false) {
173 }
174
175 TestLogCollector::~TestLogCollector() {
176 }
177
178 void TestLogCollector::Initialize(testing::UnitTest* unit_test) {
179   if (unit_test_ != NULL) {
180     CHECK_EQ(unit_test, unit_test_)
181         << "Cannot install the test log collector in multiple unit tests.";
182     return;  // Already initialized.
183   }
184
185   // Remove the default result printer and install the collector's listener
186   // which delegates to the printer.  If the default result printer has already
187   // been released, log an error and move on.
188   testing::TestEventListeners& listeners = unit_test->listeners();
189   testing::TestEventListener* default_result_printer =
190       listeners.default_result_printer();
191   if (default_result_printer == NULL) {
192     LOG(ERROR) << "Failed to initialize the test log collector on account of "
193                   "another component having released the default result "
194                   "printer.";
195   } else {
196     // Ownership of |default_release_printer| is passed to the new listener, and
197     // ownership of the new listener is passed to the unit test.
198     listeners.Append(
199         new EventListener(this, listeners.Release(default_result_printer)));
200
201     also_emit_success_logs_ = CommandLine::ForCurrentProcess()->HasSwitch(
202         switches::kAlsoEmitSuccessLogs);
203
204     unit_test_ = unit_test;
205   }
206 }
207
208 // Invoked by the listener at test program start to create the temporary log
209 // directory and initialize the logger.
210 void TestLogCollector::SetUp() {
211   if (!log_temp_dir_.CreateUniqueTempDir()) {
212     LOG(ERROR) << "Failed to create temporary directory to hold log files.";
213   } else {
214     file_logger_.reset(new FileLogger());
215     file_logger_->Initialize();
216   }
217 }
218
219 // Invoked by the listener at test start to begin collecting logs in a file.
220 void TestLogCollector::StartSessionForTest(const testing::TestInfo& test_info) {
221   if (log_temp_dir_.IsValid()) {
222     std::string log_file_name(test_info.name());
223     std::replace(log_file_name.begin(), log_file_name.end(), '/', '_');
224     log_file_name.append(kTraceLogExtension);
225     log_file_ = log_temp_dir_.path().AppendASCII(log_file_name);
226
227     file_logger_->StartLogging(log_file_);
228   }
229 }
230
231 // Invoked by the listener when a test result is produced to log an event for
232 // the result.
233 bool TestLogCollector::LogTestPartResult(
234     const testing::TestPartResult& test_part_result) {
235   // Can't handle the event if no trace session.
236   if (!file_logger_.get() || !file_logger_->is_logging())
237     return false;
238
239   if (test_part_result.type() != testing::TestPartResult::kSuccess) {
240     // Approximate Google Test's message formatting.
241     LOG(ERROR)
242         << base::StringPrintf("%s(%d): error: %s", test_part_result.file_name(),
243                               test_part_result.line_number(),
244                               test_part_result.message());
245   }
246   return true;
247 }
248
249 // Invoked by the listener at test end to dump the collected log in case of
250 // error.
251 void TestLogCollector::ProcessSessionForTest(
252     const testing::TestInfo& test_info) {
253   if (file_logger_.get() != NULL && file_logger_->is_logging()) {
254     file_logger_->StopLogging();
255
256     if (also_emit_success_logs_ || test_info.result()->Failed()) {
257       std::cerr << "----- log messages for "
258                 << test_info.test_case_name() << "." << test_info.name()
259                 << " above this line are repeated below -----" << std::endl;
260       // Dump the log to stderr.
261       logging_win::PrintLogFile(log_file_, &std::cerr);
262       std::cerr.flush();
263     }
264
265     if (!base::DeleteFile(log_file_, false))
266       LOG(ERROR) << "Failed to delete log file " << log_file_.value();
267   }
268
269   log_file_.clear();
270 }
271
272 // Invoked by the listener at test program end to shut down the logger and
273 // delete the temporary log directory.
274 void TestLogCollector::TearDown() {
275   file_logger_.reset();
276
277   ignore_result(log_temp_dir_.Delete());
278 }
279
280 }  // namespace
281
282 void InstallTestLogCollector(testing::UnitTest* unit_test) {
283   // Must be called before running any tests.
284   DCHECK(unit_test);
285   DCHECK(!unit_test->current_test_case());
286
287   g_test_log_collector.Get().Initialize(unit_test);
288 }
289
290 }  // namespace logging_win