OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 <stdlib.h> | |
6 | |
7 #include <sstream> | |
8 #include <string> | |
9 | |
10 #include "mojo/public/cpp/environment/environment.h" | |
11 #include "mojo/public/cpp/environment/logging.h" | |
12 #include "mojo/public/cpp/system/macros.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 // A macro, so it can be automatically joined with other string literals. (Not | |
16 // simply __FILE__, since that may contain a path.) | |
17 #define OUR_FILENAME "logging_unittest.cc" | |
18 | |
19 namespace mojo { | |
20 namespace { | |
21 | |
22 class PtrToMemberHelper { | |
23 public: | |
24 int member; | |
25 }; | |
26 | |
27 bool DcheckTestHelper(bool* was_called) { | |
28 *was_called = true; | |
29 return false; | |
30 } | |
31 | |
32 class LoggingTest : public testing::Test { | |
33 public: | |
34 LoggingTest() : environment_(nullptr, &kMockLogger) { | |
35 minimum_log_level_ = MOJO_LOG_LEVEL_INFO; | |
36 ResetMockLogger(); | |
37 } | |
38 ~LoggingTest() override {} | |
39 | |
40 protected: | |
41 // Note: Does not reset |minimum_log_level_|. | |
42 static void ResetMockLogger() { | |
43 log_message_was_called_ = false; | |
44 last_log_level_ = MOJO_LOG_LEVEL_INFO; | |
45 last_message_.clear(); | |
46 } | |
47 | |
48 // A function returning |bool| that shouldn't be called. | |
49 static bool NotCalledCondition() { | |
50 not_called_condition_was_called_ = true; | |
51 return false; | |
52 } | |
53 | |
54 static bool log_message_was_called() { return log_message_was_called_; } | |
55 static MojoLogLevel last_log_level() { return last_log_level_; } | |
56 static const std::string& last_message() { return last_message_; } | |
57 static bool not_called_condition_was_called() { | |
58 return not_called_condition_was_called_; | |
59 } | |
60 | |
61 private: | |
62 // Note: We record calls even if |log_level| is below |minimum_log_level_| | |
63 // (since the macros should mostly avoid this, and we want to be able to check | |
64 // that they do). | |
65 static void MockLogMessage(MojoLogLevel log_level, const char* message) { | |
66 log_message_was_called_ = true; | |
67 last_log_level_ = log_level; | |
68 last_message_ = message; | |
69 } | |
70 | |
71 static MojoLogLevel MockGetMinimumLogLevel() { return minimum_log_level_; } | |
72 | |
73 static void MockSetMinimumLogLevel(MojoLogLevel minimum_log_level) { | |
74 minimum_log_level_ = minimum_log_level; | |
75 } | |
76 | |
77 Environment environment_; | |
78 | |
79 static const MojoLogger kMockLogger; | |
80 static MojoLogLevel minimum_log_level_; | |
81 static bool log_message_was_called_; | |
82 static MojoLogLevel last_log_level_; | |
83 static std::string last_message_; | |
84 static bool not_called_condition_was_called_; | |
85 | |
86 MOJO_DISALLOW_COPY_AND_ASSIGN(LoggingTest); | |
87 }; | |
88 | |
89 // static | |
90 const MojoLogger LoggingTest::kMockLogger = { | |
91 &LoggingTest::MockLogMessage, | |
92 &LoggingTest::MockGetMinimumLogLevel, | |
93 &LoggingTest::MockSetMinimumLogLevel}; | |
94 | |
95 // static | |
96 MojoLogLevel LoggingTest::minimum_log_level_ = MOJO_LOG_LEVEL_INFO; | |
97 | |
98 // static | |
99 bool LoggingTest::log_message_was_called_ = MOJO_LOG_LEVEL_INFO; | |
100 | |
101 // static | |
102 MojoLogLevel LoggingTest::last_log_level_ = MOJO_LOG_LEVEL_INFO; | |
103 | |
104 // static | |
105 std::string LoggingTest::last_message_; | |
106 | |
107 // static | |
108 bool LoggingTest::not_called_condition_was_called_ = false; | |
109 | |
110 std::string ExpectedLogMessage(int line, const char* message) { | |
111 std::ostringstream s; | |
112 s << OUR_FILENAME "(" << line << "): " << message; | |
113 return s.str(); | |
114 } | |
115 | |
116 TEST_F(LoggingTest, InternalLogMessage) { | |
117 internal::LogMessage("foo.cc", 123, MOJO_LOG_LEVEL_INFO).stream() << "hello " | |
118 << "world"; | |
119 EXPECT_TRUE(log_message_was_called()); | |
120 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, last_log_level()); | |
121 EXPECT_EQ("foo.cc(123): hello world", last_message()); | |
122 | |
123 ResetMockLogger(); | |
124 | |
125 internal::LogMessage("./path/to/foo.cc", 123, MOJO_LOG_LEVEL_WARNING).stream() | |
126 << "hello " | |
127 << "world"; | |
128 EXPECT_TRUE(log_message_was_called()); | |
129 EXPECT_EQ(MOJO_LOG_LEVEL_WARNING, last_log_level()); | |
130 EXPECT_EQ("foo.cc(123): hello world", last_message()); | |
131 | |
132 ResetMockLogger(); | |
133 | |
134 internal::LogMessage("/path/to/foo.cc", 123, MOJO_LOG_LEVEL_ERROR).stream() | |
135 << "hello " | |
136 << "world"; | |
137 EXPECT_TRUE(log_message_was_called()); | |
138 EXPECT_EQ(MOJO_LOG_LEVEL_ERROR, last_log_level()); | |
139 EXPECT_EQ("foo.cc(123): hello world", last_message()); | |
140 | |
141 ResetMockLogger(); | |
142 | |
143 internal::LogMessage("path/to/foo.cc", 123, MOJO_LOG_LEVEL_FATAL).stream() | |
144 << "hello " | |
145 << "world"; | |
146 EXPECT_TRUE(log_message_was_called()); | |
147 EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, last_log_level()); | |
148 EXPECT_EQ("foo.cc(123): hello world", last_message()); | |
149 | |
150 ResetMockLogger(); | |
151 | |
152 internal::LogMessage(".\\xy\\foo.cc", 123, MOJO_LOG_LEVEL_VERBOSE).stream() | |
153 << "hello " | |
154 << "world"; | |
155 EXPECT_TRUE(log_message_was_called()); | |
156 EXPECT_EQ(MOJO_LOG_LEVEL_VERBOSE, last_log_level()); | |
157 EXPECT_EQ("foo.cc(123): hello world", last_message()); | |
158 | |
159 ResetMockLogger(); | |
160 | |
161 internal::LogMessage("xy\\foo.cc", 123, MOJO_LOG_LEVEL_VERBOSE - 1).stream() | |
162 << "hello " | |
163 << "world"; | |
164 EXPECT_TRUE(log_message_was_called()); | |
165 EXPECT_EQ(MOJO_LOG_LEVEL_VERBOSE - 1, last_log_level()); | |
166 EXPECT_EQ("foo.cc(123): hello world", last_message()); | |
167 | |
168 ResetMockLogger(); | |
169 | |
170 internal::LogMessage("C:\\xy\\foo.cc", 123, MOJO_LOG_LEVEL_VERBOSE - 9) | |
171 .stream() | |
172 << "hello " | |
173 << "world"; | |
174 EXPECT_TRUE(log_message_was_called()); | |
175 EXPECT_EQ(MOJO_LOG_LEVEL_VERBOSE - 9, last_log_level()); | |
176 EXPECT_EQ("foo.cc(123): hello world", last_message()); | |
177 | |
178 ResetMockLogger(); | |
179 | |
180 internal::LogMessage(__FILE__, 123, MOJO_LOG_LEVEL_INFO).stream() << "hello " | |
181 << "world"; | |
182 EXPECT_TRUE(log_message_was_called()); | |
183 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, last_log_level()); | |
184 EXPECT_EQ(OUR_FILENAME "(123): hello world", last_message()); | |
185 } | |
186 | |
187 TEST_F(LoggingTest, LogStream) { | |
188 MOJO_LOG_STREAM(INFO) << "hello"; | |
189 EXPECT_TRUE(log_message_was_called()); | |
190 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, last_log_level()); | |
191 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hello"), last_message()); | |
192 | |
193 ResetMockLogger(); | |
194 | |
195 MOJO_LOG_STREAM(ERROR) << "hi " << 123; | |
196 EXPECT_TRUE(log_message_was_called()); | |
197 EXPECT_EQ(MOJO_LOG_LEVEL_ERROR, last_log_level()); | |
198 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hi 123"), last_message()); | |
199 } | |
200 | |
201 TEST_F(LoggingTest, LazyLogStream) { | |
202 MOJO_LAZY_LOG_STREAM(INFO, true) << "hello"; | |
203 EXPECT_TRUE(log_message_was_called()); | |
204 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, last_log_level()); | |
205 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hello"), last_message()); | |
206 | |
207 ResetMockLogger(); | |
208 | |
209 MOJO_LAZY_LOG_STREAM(ERROR, true) << "hi " << 123; | |
210 EXPECT_TRUE(log_message_was_called()); | |
211 EXPECT_EQ(MOJO_LOG_LEVEL_ERROR, last_log_level()); | |
212 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hi 123"), last_message()); | |
213 | |
214 ResetMockLogger(); | |
215 | |
216 MOJO_LAZY_LOG_STREAM(INFO, false) << "hello"; | |
217 EXPECT_FALSE(log_message_was_called()); | |
218 | |
219 ResetMockLogger(); | |
220 | |
221 MOJO_LAZY_LOG_STREAM(FATAL, false) << "hello"; | |
222 EXPECT_FALSE(log_message_was_called()); | |
223 | |
224 ResetMockLogger(); | |
225 | |
226 PtrToMemberHelper helper; | |
227 helper.member = 1; | |
228 int PtrToMemberHelper::*member_ptr = &PtrToMemberHelper::member; | |
229 | |
230 // This probably fails to compile if we forget to parenthesize the condition | |
231 // in the macro (.* has lower precedence than !, which can't apply to | |
232 // |helper|). | |
233 MOJO_LAZY_LOG_STREAM(ERROR, helper.*member_ptr == 1) << "hello"; | |
234 EXPECT_TRUE(log_message_was_called()); | |
235 | |
236 ResetMockLogger(); | |
237 | |
238 MOJO_LAZY_LOG_STREAM(WARNING, helper.*member_ptr == 0) << "hello"; | |
239 EXPECT_FALSE(log_message_was_called()); | |
240 } | |
241 | |
242 TEST_F(LoggingTest, ShouldLog) { | |
243 // We start at |MOJO_LOG_LEVEL_INFO|. | |
244 EXPECT_FALSE(MOJO_SHOULD_LOG(VERBOSE)); | |
245 EXPECT_TRUE(MOJO_SHOULD_LOG(INFO)); | |
246 EXPECT_TRUE(MOJO_SHOULD_LOG(WARNING)); | |
247 EXPECT_TRUE(MOJO_SHOULD_LOG(ERROR)); | |
248 EXPECT_TRUE(MOJO_SHOULD_LOG(FATAL)); | |
249 | |
250 Environment::GetDefaultLogger()->SetMinimumLogLevel(MOJO_LOG_LEVEL_ERROR); | |
251 EXPECT_FALSE(MOJO_SHOULD_LOG(VERBOSE)); | |
252 EXPECT_FALSE(MOJO_SHOULD_LOG(INFO)); | |
253 EXPECT_FALSE(MOJO_SHOULD_LOG(WARNING)); | |
254 EXPECT_TRUE(MOJO_SHOULD_LOG(ERROR)); | |
255 EXPECT_TRUE(MOJO_SHOULD_LOG(FATAL)); | |
256 | |
257 Environment::GetDefaultLogger()->SetMinimumLogLevel(MOJO_LOG_LEVEL_VERBOSE - | |
258 1); | |
259 EXPECT_TRUE(MOJO_SHOULD_LOG(VERBOSE)); | |
260 EXPECT_TRUE(MOJO_SHOULD_LOG(INFO)); | |
261 EXPECT_TRUE(MOJO_SHOULD_LOG(WARNING)); | |
262 EXPECT_TRUE(MOJO_SHOULD_LOG(ERROR)); | |
263 EXPECT_TRUE(MOJO_SHOULD_LOG(FATAL)); | |
264 } | |
265 | |
266 TEST_F(LoggingTest, Log) { | |
267 // We start at |MOJO_LOG_LEVEL_INFO|. | |
268 MOJO_LOG(VERBOSE) << "hello"; | |
269 EXPECT_FALSE(log_message_was_called()); | |
270 | |
271 ResetMockLogger(); | |
272 | |
273 MOJO_LOG(INFO) << "hello"; | |
274 EXPECT_TRUE(log_message_was_called()); | |
275 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, last_log_level()); | |
276 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hello"), last_message()); | |
277 | |
278 ResetMockLogger(); | |
279 | |
280 MOJO_LOG(ERROR) << "hello"; | |
281 EXPECT_TRUE(log_message_was_called()); | |
282 EXPECT_EQ(MOJO_LOG_LEVEL_ERROR, last_log_level()); | |
283 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hello"), last_message()); | |
284 | |
285 ResetMockLogger(); | |
286 | |
287 Environment::GetDefaultLogger()->SetMinimumLogLevel(MOJO_LOG_LEVEL_ERROR); | |
288 | |
289 MOJO_LOG(VERBOSE) << "hello"; | |
290 EXPECT_FALSE(log_message_was_called()); | |
291 | |
292 ResetMockLogger(); | |
293 | |
294 MOJO_LOG(INFO) << "hello"; | |
295 EXPECT_FALSE(log_message_was_called()); | |
296 | |
297 ResetMockLogger(); | |
298 | |
299 MOJO_LOG(ERROR) << "hello"; | |
300 EXPECT_TRUE(log_message_was_called()); | |
301 EXPECT_EQ(MOJO_LOG_LEVEL_ERROR, last_log_level()); | |
302 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hello"), last_message()); | |
303 } | |
304 | |
305 TEST_F(LoggingTest, LogIf) { | |
306 // We start at |MOJO_LOG_LEVEL_INFO|. | |
307 MOJO_LOG_IF(VERBOSE, true) << "hello"; | |
308 EXPECT_FALSE(log_message_was_called()); | |
309 | |
310 ResetMockLogger(); | |
311 | |
312 MOJO_LOG_IF(VERBOSE, false) << "hello"; | |
313 EXPECT_FALSE(log_message_was_called()); | |
314 | |
315 ResetMockLogger(); | |
316 Environment::GetDefaultLogger()->SetMinimumLogLevel(MOJO_LOG_LEVEL_ERROR); | |
317 | |
318 bool x = true; | |
319 // Also try to make sure that we parenthesize the condition properly. | |
320 MOJO_LOG_IF(INFO, false || x) << "hello"; | |
321 EXPECT_FALSE(log_message_was_called()); | |
322 | |
323 ResetMockLogger(); | |
324 | |
325 MOJO_LOG_IF(INFO, 0 != 1) << "hello"; | |
326 EXPECT_FALSE(log_message_was_called()); | |
327 | |
328 ResetMockLogger(); | |
329 | |
330 MOJO_LOG_IF(WARNING, 1 + 1 == 2) << "hello"; | |
331 EXPECT_FALSE(log_message_was_called()); | |
332 | |
333 ResetMockLogger(); | |
334 | |
335 MOJO_LOG_IF(ERROR, 1 * 2 == 2) << "hello"; | |
336 EXPECT_TRUE(log_message_was_called()); | |
337 EXPECT_EQ(MOJO_LOG_LEVEL_ERROR, last_log_level()); | |
338 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 3, "hello"), last_message()); | |
339 | |
340 ResetMockLogger(); | |
341 | |
342 MOJO_LOG_IF(FATAL, 1 * 2 == 3) << "hello"; | |
343 EXPECT_FALSE(log_message_was_called()); | |
344 | |
345 ResetMockLogger(); | |
346 | |
347 // |MOJO_LOG_IF()| shouldn't evaluate its condition if the level is below the | |
348 // minimum. | |
349 MOJO_LOG_IF(INFO, NotCalledCondition()) << "hello"; | |
350 EXPECT_FALSE(not_called_condition_was_called()); | |
351 EXPECT_FALSE(log_message_was_called()); | |
352 } | |
353 | |
354 TEST_F(LoggingTest, Check) { | |
355 MOJO_CHECK(true) << "hello"; | |
356 EXPECT_FALSE(log_message_was_called()); | |
357 | |
358 ResetMockLogger(); | |
359 | |
360 PtrToMemberHelper helper; | |
361 helper.member = 0; | |
362 int PtrToMemberHelper::*member_ptr = &PtrToMemberHelper::member; | |
363 | |
364 // Also try to make sure that we parenthesize the condition properly. | |
365 MOJO_CHECK(helper.*member_ptr == 1) << "hello"; | |
366 EXPECT_TRUE(log_message_was_called()); | |
367 EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, last_log_level()); | |
368 // Different compilers have different ideas about the line number of a split | |
369 // line. | |
370 int line = __LINE__; | |
371 EXPECT_EQ(ExpectedLogMessage(line - 5, | |
372 "Check failed: helper.*member_ptr == 1. hello"), | |
373 last_message()); | |
374 | |
375 ResetMockLogger(); | |
376 | |
377 // Also test a "naked" |MOJO_CHECK()|s. | |
378 MOJO_CHECK(1 + 2 == 3); | |
379 EXPECT_FALSE(log_message_was_called()); | |
380 } | |
381 | |
382 TEST_F(LoggingTest, Dlog) { | |
383 // We start at |MOJO_LOG_LEVEL_INFO|. | |
384 MOJO_DLOG(VERBOSE) << "hello"; | |
385 EXPECT_FALSE(log_message_was_called()); | |
386 | |
387 ResetMockLogger(); | |
388 | |
389 MOJO_DLOG(INFO) << "hello"; | |
390 #ifdef NDEBUG | |
391 EXPECT_FALSE(log_message_was_called()); | |
392 #else | |
393 EXPECT_TRUE(log_message_was_called()); | |
394 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, last_log_level()); | |
395 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 6, "hello"), last_message()); | |
396 #endif | |
397 } | |
398 | |
399 TEST_F(LoggingTest, DlogIf) { | |
400 // We start at |MOJO_LOG_LEVEL_INFO|. It shouldn't evaluate the condition in | |
401 // this case. | |
402 MOJO_DLOG_IF(VERBOSE, NotCalledCondition()) << "hello"; | |
403 EXPECT_FALSE(not_called_condition_was_called()); | |
404 EXPECT_FALSE(log_message_was_called()); | |
405 | |
406 ResetMockLogger(); | |
407 | |
408 MOJO_DLOG_IF(INFO, 1 == 0) << "hello"; | |
409 EXPECT_FALSE(log_message_was_called()); | |
410 | |
411 ResetMockLogger(); | |
412 | |
413 MOJO_DLOG_IF(INFO, 1 == 1) << "hello"; | |
414 #ifdef NDEBUG | |
415 EXPECT_FALSE(log_message_was_called()); | |
416 #else | |
417 EXPECT_TRUE(log_message_was_called()); | |
418 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, last_log_level()); | |
419 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 6, "hello"), last_message()); | |
420 #endif | |
421 | |
422 ResetMockLogger(); | |
423 | |
424 // |MOJO_DLOG_IF()| shouldn't compile its condition for non-debug builds. | |
425 #ifndef NDEBUG | |
426 bool debug_only = true; | |
427 #endif | |
428 MOJO_DLOG_IF(WARNING, debug_only) << "hello"; | |
429 #ifdef NDEBUG | |
430 EXPECT_FALSE(log_message_was_called()); | |
431 #else | |
432 EXPECT_TRUE(log_message_was_called()); | |
433 EXPECT_EQ(MOJO_LOG_LEVEL_WARNING, last_log_level()); | |
434 EXPECT_EQ(ExpectedLogMessage(__LINE__ - 6, "hello"), last_message()); | |
435 #endif | |
436 } | |
437 | |
438 TEST_F(LoggingTest, Dcheck) { | |
439 MOJO_DCHECK(true); | |
440 EXPECT_FALSE(log_message_was_called()); | |
441 | |
442 ResetMockLogger(); | |
443 | |
444 MOJO_DCHECK(true) << "hello"; | |
445 EXPECT_FALSE(log_message_was_called()); | |
446 | |
447 ResetMockLogger(); | |
448 | |
449 // |MOJO_DCHECK()| should compile (but not evaluate) its condition even for | |
450 // non-debug builds. (Hopefully, we'll get an unused variable error if it | |
451 // fails to compile the condition.) | |
452 bool was_called = false; | |
453 MOJO_DCHECK(DcheckTestHelper(&was_called)) << "hello"; | |
454 #ifdef NDEBUG | |
455 EXPECT_FALSE(was_called); | |
456 EXPECT_FALSE(log_message_was_called()); | |
457 #else | |
458 EXPECT_TRUE(was_called); | |
459 EXPECT_TRUE(log_message_was_called()); | |
460 EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, last_log_level()); | |
461 // Different compilers have different ideas about the line number of a split | |
462 // line. | |
463 int line = __LINE__; | |
464 EXPECT_EQ( | |
465 ExpectedLogMessage(line - 10, | |
466 "Check failed: DcheckTestHelper(&was_called). hello"), | |
467 last_message()); | |
468 #endif | |
469 | |
470 ResetMockLogger(); | |
471 | |
472 // Also try to make sure that we parenthesize the condition properly. | |
473 bool x = true; | |
474 MOJO_DCHECK(false || x) << "hello"; | |
475 EXPECT_FALSE(log_message_was_called()); | |
476 } | |
477 | |
478 } // namespace | |
479 } // namespace mojo | |
OLD | NEW |