1 /*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "android-base/logging.h"
18
19 #include <libgen.h>
20
21 #if defined(_WIN32)
22 #include <signal.h>
23 #endif
24
25 #include <memory>
26 #include <regex>
27 #include <string>
28 #include <thread>
29
30 #include "android-base/file.h"
31 #include "android-base/scopeguard.h"
32 #include "android-base/stringprintf.h"
33 #include "android-base/test_utils.h"
34
35 #include <gtest/gtest.h>
36
37 #ifdef __ANDROID__
38 #define HOST_TEST(suite, name) TEST(suite, DISABLED_ ## name)
39 #else
40 #define HOST_TEST(suite, name) TEST(suite, name)
41 #endif
42
43 #if defined(_WIN32)
ExitSignalAbortHandler(int)44 static void ExitSignalAbortHandler(int) {
45 _exit(3);
46 }
47 #endif
48
SuppressAbortUI()49 static void SuppressAbortUI() {
50 #if defined(_WIN32)
51 // We really just want to call _set_abort_behavior(0, _CALL_REPORTFAULT) to
52 // suppress the Windows Error Reporting dialog box, but that API is not
53 // available in the OS-supplied C Runtime, msvcrt.dll, that we currently
54 // use (it is available in the Visual Studio C runtime).
55 //
56 // Instead, we setup a SIGABRT handler, which is called in abort() right
57 // before calling Windows Error Reporting. In the handler, we exit the
58 // process just like abort() does.
59 ASSERT_NE(SIG_ERR, signal(SIGABRT, ExitSignalAbortHandler));
60 #endif
61 }
62
TEST(logging,CHECK)63 TEST(logging, CHECK) {
64 ASSERT_DEATH({SuppressAbortUI(); CHECK(false);}, "Check failed: false ");
65 CHECK(true);
66
67 ASSERT_DEATH({SuppressAbortUI(); CHECK_EQ(0, 1);}, "Check failed: 0 == 1 ");
68 CHECK_EQ(0, 0);
69
70 std::unique_ptr<int> p;
71 ASSERT_DEATH(CHECK_NE(p, nullptr), "Check failed");
72 CHECK_EQ(p, nullptr);
73 CHECK_EQ(p, p);
74
75 const char* kText = "Some text";
76 ASSERT_DEATH(CHECK_NE(kText, kText), "Check failed");
77 ASSERT_DEATH(CHECK_EQ(kText, nullptr), "Check failed.*null");
78 CHECK_EQ(kText, kText);
79
80 ASSERT_DEATH({SuppressAbortUI(); CHECK_STREQ("foo", "bar");},
81 R"(Check failed: "foo" == "bar")");
82 CHECK_STREQ("foo", "foo");
83
84 // Test whether CHECK() and CHECK_STREQ() have a dangling if with no else.
85 bool flag = false;
86 if (true)
87 CHECK(true);
88 else
89 flag = true;
90 EXPECT_FALSE(flag) << "CHECK macro probably has a dangling if with no else";
91
92 flag = false;
93 if (true)
94 CHECK_STREQ("foo", "foo");
95 else
96 flag = true;
97 EXPECT_FALSE(flag) << "CHECK_STREQ probably has a dangling if with no else";
98 }
99
TEST(logging,DCHECK)100 TEST(logging, DCHECK) {
101 if (android::base::kEnableDChecks) {
102 ASSERT_DEATH({SuppressAbortUI(); DCHECK(false);}, "Check failed: false ");
103 }
104 DCHECK(true);
105
106 if (android::base::kEnableDChecks) {
107 ASSERT_DEATH({SuppressAbortUI(); DCHECK_EQ(0, 1);}, "Check failed: 0 == 1 ");
108 }
109 DCHECK_EQ(0, 0);
110
111 std::unique_ptr<int> p;
112 if (android::base::kEnableDChecks) {
113 ASSERT_DEATH(DCHECK_NE(p, nullptr), "Check failed");
114 }
115 DCHECK_EQ(p, nullptr);
116 DCHECK_EQ(p, p);
117
118 if (android::base::kEnableDChecks) {
119 ASSERT_DEATH({SuppressAbortUI(); DCHECK_STREQ("foo", "bar");},
120 R"(Check failed: "foo" == "bar")");
121 }
122 DCHECK_STREQ("foo", "foo");
123
124 // No testing whether we have a dangling else, possibly. That's inherent to the if (constexpr)
125 // setup we intentionally chose to force type-checks of debug code even in release builds (so
126 // we don't get more bit-rot).
127 }
128
129
130 #define CHECK_WOULD_LOG_DISABLED(severity) \
131 static_assert(android::base::severity < android::base::FATAL, "Bad input"); \
132 for (size_t i = static_cast<size_t>(android::base::severity) + 1; \
133 i <= static_cast<size_t>(android::base::FATAL); \
134 ++i) { \
135 { \
136 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
137 EXPECT_FALSE(WOULD_LOG(severity)) << i; \
138 } \
139 { \
140 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
141 EXPECT_FALSE(WOULD_LOG(::android::base::severity)) << i; \
142 } \
143 } \
144
145 #define CHECK_WOULD_LOG_ENABLED(severity) \
146 for (size_t i = static_cast<size_t>(android::base::VERBOSE); \
147 i <= static_cast<size_t>(android::base::severity); \
148 ++i) { \
149 { \
150 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
151 EXPECT_TRUE(WOULD_LOG(severity)) << i; \
152 } \
153 { \
154 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
155 EXPECT_TRUE(WOULD_LOG(::android::base::severity)) << i; \
156 } \
157 } \
158
TEST(logging,WOULD_LOG_FATAL)159 TEST(logging, WOULD_LOG_FATAL) {
160 CHECK_WOULD_LOG_ENABLED(FATAL);
161 }
162
TEST(logging,WOULD_LOG_FATAL_WITHOUT_ABORT_enabled)163 TEST(logging, WOULD_LOG_FATAL_WITHOUT_ABORT_enabled) {
164 CHECK_WOULD_LOG_ENABLED(FATAL_WITHOUT_ABORT);
165 }
166
TEST(logging,WOULD_LOG_ERROR_disabled)167 TEST(logging, WOULD_LOG_ERROR_disabled) {
168 CHECK_WOULD_LOG_DISABLED(ERROR);
169 }
170
TEST(logging,WOULD_LOG_ERROR_enabled)171 TEST(logging, WOULD_LOG_ERROR_enabled) {
172 CHECK_WOULD_LOG_ENABLED(ERROR);
173 }
174
TEST(logging,WOULD_LOG_WARNING_disabled)175 TEST(logging, WOULD_LOG_WARNING_disabled) {
176 CHECK_WOULD_LOG_DISABLED(WARNING);
177 }
178
TEST(logging,WOULD_LOG_WARNING_enabled)179 TEST(logging, WOULD_LOG_WARNING_enabled) {
180 CHECK_WOULD_LOG_ENABLED(WARNING);
181 }
182
TEST(logging,WOULD_LOG_INFO_disabled)183 TEST(logging, WOULD_LOG_INFO_disabled) {
184 CHECK_WOULD_LOG_DISABLED(INFO);
185 }
186
TEST(logging,WOULD_LOG_INFO_enabled)187 TEST(logging, WOULD_LOG_INFO_enabled) {
188 CHECK_WOULD_LOG_ENABLED(INFO);
189 }
190
TEST(logging,WOULD_LOG_DEBUG_disabled)191 TEST(logging, WOULD_LOG_DEBUG_disabled) {
192 CHECK_WOULD_LOG_DISABLED(DEBUG);
193 }
194
TEST(logging,WOULD_LOG_DEBUG_enabled)195 TEST(logging, WOULD_LOG_DEBUG_enabled) {
196 CHECK_WOULD_LOG_ENABLED(DEBUG);
197 }
198
TEST(logging,WOULD_LOG_VERBOSE_disabled)199 TEST(logging, WOULD_LOG_VERBOSE_disabled) {
200 CHECK_WOULD_LOG_DISABLED(VERBOSE);
201 }
202
TEST(logging,WOULD_LOG_VERBOSE_enabled)203 TEST(logging, WOULD_LOG_VERBOSE_enabled) {
204 CHECK_WOULD_LOG_ENABLED(VERBOSE);
205 }
206
207 #undef CHECK_WOULD_LOG_DISABLED
208 #undef CHECK_WOULD_LOG_ENABLED
209
210
211 #if !defined(_WIN32)
make_log_pattern(const char * expected_tag,android::base::LogSeverity severity,const char * message)212 static std::string make_log_pattern(const char* expected_tag, android::base::LogSeverity severity,
213 const char* message) {
214 static const char log_characters[] = "VDIWEFF";
215 static_assert(arraysize(log_characters) - 1 == android::base::FATAL + 1,
216 "Mismatch in size of log_characters and values in LogSeverity");
217 char log_char = log_characters[severity];
218 std::string holder(__FILE__);
219
220 // `message` can have a function name like "TestBody()". The parentheses should be escaped,
221 // otherwise it will be interpreted as a capturing group when it is used as a regex. Below
222 // replaces either '(' or ')' to '\(' or '\)', respectively.
223 std::regex parentheses(R"(\(|\))");
224 std::string message_escaped = std::regex_replace(message, parentheses, R"(\$&)");
225
226 const char* tag_pattern = expected_tag != nullptr ? expected_tag : ".+";
227 return android::base::StringPrintf(
228 R"(\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} \s*\d+ \s*\d+ %c %s\s*: %s:\d+ %s)", log_char,
229 tag_pattern, basename(&holder[0]), message_escaped.c_str());
230 }
231 #endif
232
CheckMessage(const std::string & output,android::base::LogSeverity severity,const char * expected,const char * expected_tag=nullptr)233 static void CheckMessage(const std::string& output, android::base::LogSeverity severity,
234 const char* expected, const char* expected_tag = nullptr) {
235 // We can't usefully check the output of any of these on Windows because we
236 // don't have std::regex, but we can at least make sure we printed at least as
237 // many characters are in the log message.
238 ASSERT_GT(output.length(), strlen(expected));
239 ASSERT_NE(nullptr, strstr(output.c_str(), expected)) << output;
240 if (expected_tag != nullptr) {
241 ASSERT_NE(nullptr, strstr(output.c_str(), expected_tag)) << output;
242 }
243
244 #if !defined(_WIN32)
245 std::string regex_str = make_log_pattern(expected_tag, severity, expected);
246 std::regex message_regex(regex_str);
247 ASSERT_TRUE(std::regex_search(output, message_regex)) << output;
248 #endif
249 }
250
CheckMessage(CapturedStderr & cap,android::base::LogSeverity severity,const char * expected,const char * expected_tag=nullptr)251 static void CheckMessage(CapturedStderr& cap, android::base::LogSeverity severity,
252 const char* expected, const char* expected_tag = nullptr) {
253 cap.Stop();
254 std::string output = cap.str();
255 return CheckMessage(output, severity, expected, expected_tag);
256 }
257
258 #define CHECK_LOG_STREAM_DISABLED(severity) \
259 { \
260 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
261 CapturedStderr cap1; \
262 LOG_STREAM(severity) << "foo bar"; \
263 cap1.Stop(); \
264 ASSERT_EQ("", cap1.str()); \
265 } \
266 { \
267 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
268 CapturedStderr cap1; \
269 LOG_STREAM(::android::base::severity) << "foo bar"; \
270 cap1.Stop(); \
271 ASSERT_EQ("", cap1.str()); \
272 }
273
274 #define CHECK_LOG_STREAM_ENABLED(severity) \
275 { \
276 android::base::ScopedLogSeverity sls2(android::base::severity); \
277 CapturedStderr cap2; \
278 LOG_STREAM(severity) << "foobar"; \
279 CheckMessage(cap2, android::base::severity, "foobar"); \
280 } \
281 { \
282 android::base::ScopedLogSeverity sls2(android::base::severity); \
283 CapturedStderr cap2; \
284 LOG_STREAM(::android::base::severity) << "foobar"; \
285 CheckMessage(cap2, android::base::severity, "foobar"); \
286 } \
287
TEST(logging,LOG_STREAM_FATAL_WITHOUT_ABORT_enabled)288 TEST(logging, LOG_STREAM_FATAL_WITHOUT_ABORT_enabled) {
289 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_STREAM_ENABLED(FATAL_WITHOUT_ABORT));
290 }
291
TEST(logging,LOG_STREAM_ERROR_disabled)292 TEST(logging, LOG_STREAM_ERROR_disabled) {
293 CHECK_LOG_STREAM_DISABLED(ERROR);
294 }
295
TEST(logging,LOG_STREAM_ERROR_enabled)296 TEST(logging, LOG_STREAM_ERROR_enabled) {
297 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_STREAM_ENABLED(ERROR));
298 }
299
TEST(logging,LOG_STREAM_WARNING_disabled)300 TEST(logging, LOG_STREAM_WARNING_disabled) {
301 CHECK_LOG_STREAM_DISABLED(WARNING);
302 }
303
TEST(logging,LOG_STREAM_WARNING_enabled)304 TEST(logging, LOG_STREAM_WARNING_enabled) {
305 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_STREAM_ENABLED(WARNING));
306 }
307
TEST(logging,LOG_STREAM_INFO_disabled)308 TEST(logging, LOG_STREAM_INFO_disabled) {
309 CHECK_LOG_STREAM_DISABLED(INFO);
310 }
311
TEST(logging,LOG_STREAM_INFO_enabled)312 TEST(logging, LOG_STREAM_INFO_enabled) {
313 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_STREAM_ENABLED(INFO));
314 }
315
TEST(logging,LOG_STREAM_DEBUG_disabled)316 TEST(logging, LOG_STREAM_DEBUG_disabled) {
317 CHECK_LOG_STREAM_DISABLED(DEBUG);
318 }
319
TEST(logging,LOG_STREAM_DEBUG_enabled)320 TEST(logging, LOG_STREAM_DEBUG_enabled) {
321 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_STREAM_ENABLED(DEBUG));
322 }
323
TEST(logging,LOG_STREAM_VERBOSE_disabled)324 TEST(logging, LOG_STREAM_VERBOSE_disabled) {
325 CHECK_LOG_STREAM_DISABLED(VERBOSE);
326 }
327
TEST(logging,LOG_STREAM_VERBOSE_enabled)328 TEST(logging, LOG_STREAM_VERBOSE_enabled) {
329 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_STREAM_ENABLED(VERBOSE));
330 }
331
332 #undef CHECK_LOG_STREAM_DISABLED
333 #undef CHECK_LOG_STREAM_ENABLED
334
335 #define CHECK_LOG_DISABLED(severity) \
336 { \
337 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
338 CapturedStderr cap1; \
339 LOG(severity) << "foo bar"; \
340 cap1.Stop(); \
341 ASSERT_EQ("", cap1.str()); \
342 } \
343 { \
344 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
345 CapturedStderr cap1; \
346 LOG(::android::base::severity) << "foo bar"; \
347 cap1.Stop(); \
348 ASSERT_EQ("", cap1.str()); \
349 }
350
351 #define CHECK_LOG_ENABLED(severity) \
352 { \
353 android::base::ScopedLogSeverity sls2(android::base::severity); \
354 CapturedStderr cap2; \
355 LOG(severity) << "foobar"; \
356 CheckMessage(cap2, android::base::severity, "foobar"); \
357 } \
358 { \
359 android::base::ScopedLogSeverity sls2(android::base::severity); \
360 CapturedStderr cap2; \
361 LOG(::android::base::severity) << "foobar"; \
362 CheckMessage(cap2, android::base::severity, "foobar"); \
363 } \
364
TEST(logging,LOG_FATAL)365 TEST(logging, LOG_FATAL) {
366 ASSERT_DEATH({SuppressAbortUI(); LOG(FATAL) << "foobar";}, "foobar");
367 ASSERT_DEATH({SuppressAbortUI(); LOG(::android::base::FATAL) << "foobar";}, "foobar");
368 }
369
TEST(logging,LOG_FATAL_WITHOUT_ABORT_enabled)370 TEST(logging, LOG_FATAL_WITHOUT_ABORT_enabled) {
371 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_ENABLED(FATAL_WITHOUT_ABORT));
372 }
373
TEST(logging,LOG_ERROR_disabled)374 TEST(logging, LOG_ERROR_disabled) {
375 CHECK_LOG_DISABLED(ERROR);
376 }
377
TEST(logging,LOG_ERROR_enabled)378 TEST(logging, LOG_ERROR_enabled) {
379 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_ENABLED(ERROR));
380 }
381
TEST(logging,LOG_WARNING_disabled)382 TEST(logging, LOG_WARNING_disabled) {
383 CHECK_LOG_DISABLED(WARNING);
384 }
385
TEST(logging,LOG_WARNING_enabled)386 TEST(logging, LOG_WARNING_enabled) {
387 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_ENABLED(WARNING));
388 }
389
TEST(logging,LOG_INFO_disabled)390 TEST(logging, LOG_INFO_disabled) {
391 CHECK_LOG_DISABLED(INFO);
392 }
393
TEST(logging,LOG_INFO_enabled)394 TEST(logging, LOG_INFO_enabled) {
395 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_ENABLED(INFO));
396 }
397
TEST(logging,LOG_DEBUG_disabled)398 TEST(logging, LOG_DEBUG_disabled) {
399 CHECK_LOG_DISABLED(DEBUG);
400 }
401
TEST(logging,LOG_DEBUG_enabled)402 TEST(logging, LOG_DEBUG_enabled) {
403 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_ENABLED(DEBUG));
404 }
405
TEST(logging,LOG_VERBOSE_disabled)406 TEST(logging, LOG_VERBOSE_disabled) {
407 CHECK_LOG_DISABLED(VERBOSE);
408 }
409
TEST(logging,LOG_VERBOSE_enabled)410 TEST(logging, LOG_VERBOSE_enabled) {
411 ASSERT_NO_FATAL_FAILURE(CHECK_LOG_ENABLED(VERBOSE));
412 }
413
414 #undef CHECK_LOG_DISABLED
415 #undef CHECK_LOG_ENABLED
416
TEST(logging,LOG_complex_param)417 TEST(logging, LOG_complex_param) {
418 #define CHECK_LOG_COMBINATION(use_scoped_log_severity_info, use_logging_severity_info) \
419 { \
420 android::base::ScopedLogSeverity sls( \
421 (use_scoped_log_severity_info) ? ::android::base::INFO : ::android::base::WARNING); \
422 CapturedStderr cap; \
423 LOG((use_logging_severity_info) ? ::android::base::INFO : ::android::base::WARNING) \
424 << "foobar"; \
425 if ((use_scoped_log_severity_info) || !(use_logging_severity_info)) { \
426 ASSERT_NO_FATAL_FAILURE(CheckMessage( \
427 cap, (use_logging_severity_info) ? ::android::base::INFO : ::android::base::WARNING, \
428 "foobar")); \
429 } else { \
430 cap.Stop(); \
431 ASSERT_EQ("", cap.str()); \
432 } \
433 }
434
435 CHECK_LOG_COMBINATION(false,false);
436 CHECK_LOG_COMBINATION(false,true);
437 CHECK_LOG_COMBINATION(true,false);
438 CHECK_LOG_COMBINATION(true,true);
439
440 #undef CHECK_LOG_COMBINATION
441 }
442
443
TEST(logging,LOG_does_not_clobber_errno)444 TEST(logging, LOG_does_not_clobber_errno) {
445 CapturedStderr cap;
446 errno = 12345;
447 LOG(INFO) << (errno = 67890);
448 EXPECT_EQ(12345, errno) << "errno was not restored";
449
450 ASSERT_NO_FATAL_FAILURE(CheckMessage(cap, android::base::INFO, "67890"));
451 }
452
TEST(logging,PLOG_does_not_clobber_errno)453 TEST(logging, PLOG_does_not_clobber_errno) {
454 CapturedStderr cap;
455 errno = 12345;
456 PLOG(INFO) << (errno = 67890);
457 EXPECT_EQ(12345, errno) << "errno was not restored";
458
459 ASSERT_NO_FATAL_FAILURE(CheckMessage(cap, android::base::INFO, "67890"));
460 }
461
TEST(logging,LOG_does_not_have_dangling_if)462 TEST(logging, LOG_does_not_have_dangling_if) {
463 CapturedStderr cap; // So the logging below has no side-effects.
464
465 // Do the test two ways: once where we hypothesize that LOG()'s if
466 // will evaluate to true (when severity is high enough) and once when we
467 // expect it to evaluate to false (when severity is not high enough).
468 bool flag = false;
469 if (true)
470 LOG(INFO) << "foobar";
471 else
472 flag = true;
473
474 EXPECT_FALSE(flag) << "LOG macro probably has a dangling if with no else";
475
476 flag = false;
477 if (true)
478 LOG(VERBOSE) << "foobar";
479 else
480 flag = true;
481
482 EXPECT_FALSE(flag) << "LOG macro probably has a dangling if with no else";
483 }
484
485 #define CHECK_PLOG_DISABLED(severity) \
486 { \
487 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
488 CapturedStderr cap1; \
489 PLOG(severity) << "foo bar"; \
490 cap1.Stop(); \
491 ASSERT_EQ("", cap1.str()); \
492 } \
493 { \
494 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
495 CapturedStderr cap1; \
496 PLOG(severity) << "foo bar"; \
497 cap1.Stop(); \
498 ASSERT_EQ("", cap1.str()); \
499 }
500
501 #define CHECK_PLOG_ENABLED(severity) \
502 { \
503 android::base::ScopedLogSeverity sls2(android::base::severity); \
504 CapturedStderr cap2; \
505 errno = ENOENT; \
506 PLOG(severity) << "foobar"; \
507 CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
508 } \
509 { \
510 android::base::ScopedLogSeverity sls2(android::base::severity); \
511 CapturedStderr cap2; \
512 errno = ENOENT; \
513 PLOG(severity) << "foobar"; \
514 CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
515 } \
516
TEST(logging,PLOG_FATAL)517 TEST(logging, PLOG_FATAL) {
518 ASSERT_DEATH({SuppressAbortUI(); PLOG(FATAL) << "foobar";}, "foobar");
519 ASSERT_DEATH({SuppressAbortUI(); PLOG(::android::base::FATAL) << "foobar";}, "foobar");
520 }
521
TEST(logging,PLOG_FATAL_WITHOUT_ABORT_enabled)522 TEST(logging, PLOG_FATAL_WITHOUT_ABORT_enabled) {
523 ASSERT_NO_FATAL_FAILURE(CHECK_PLOG_ENABLED(FATAL_WITHOUT_ABORT));
524 }
525
TEST(logging,PLOG_ERROR_disabled)526 TEST(logging, PLOG_ERROR_disabled) {
527 CHECK_PLOG_DISABLED(ERROR);
528 }
529
TEST(logging,PLOG_ERROR_enabled)530 TEST(logging, PLOG_ERROR_enabled) {
531 ASSERT_NO_FATAL_FAILURE(CHECK_PLOG_ENABLED(ERROR));
532 }
533
TEST(logging,PLOG_WARNING_disabled)534 TEST(logging, PLOG_WARNING_disabled) {
535 CHECK_PLOG_DISABLED(WARNING);
536 }
537
TEST(logging,PLOG_WARNING_enabled)538 TEST(logging, PLOG_WARNING_enabled) {
539 ASSERT_NO_FATAL_FAILURE(CHECK_PLOG_ENABLED(WARNING));
540 }
541
TEST(logging,PLOG_INFO_disabled)542 TEST(logging, PLOG_INFO_disabled) {
543 CHECK_PLOG_DISABLED(INFO);
544 }
545
TEST(logging,PLOG_INFO_enabled)546 TEST(logging, PLOG_INFO_enabled) {
547 ASSERT_NO_FATAL_FAILURE(CHECK_PLOG_ENABLED(INFO));
548 }
549
TEST(logging,PLOG_DEBUG_disabled)550 TEST(logging, PLOG_DEBUG_disabled) {
551 CHECK_PLOG_DISABLED(DEBUG);
552 }
553
TEST(logging,PLOG_DEBUG_enabled)554 TEST(logging, PLOG_DEBUG_enabled) {
555 ASSERT_NO_FATAL_FAILURE(CHECK_PLOG_ENABLED(DEBUG));
556 }
557
TEST(logging,PLOG_VERBOSE_disabled)558 TEST(logging, PLOG_VERBOSE_disabled) {
559 CHECK_PLOG_DISABLED(VERBOSE);
560 }
561
TEST(logging,PLOG_VERBOSE_enabled)562 TEST(logging, PLOG_VERBOSE_enabled) {
563 ASSERT_NO_FATAL_FAILURE(CHECK_PLOG_ENABLED(VERBOSE));
564 }
565
566 #undef CHECK_PLOG_DISABLED
567 #undef CHECK_PLOG_ENABLED
568
569
TEST(logging,UNIMPLEMENTED)570 TEST(logging, UNIMPLEMENTED) {
571 std::string expected = android::base::StringPrintf("%s unimplemented ", __PRETTY_FUNCTION__);
572
573 CapturedStderr cap;
574 errno = ENOENT;
575 UNIMPLEMENTED(ERROR);
576 ASSERT_NO_FATAL_FAILURE(CheckMessage(cap, android::base::ERROR, expected.c_str()));
577 }
578
NoopAborter(const char * msg ATTRIBUTE_UNUSED)579 static void NoopAborter(const char* msg ATTRIBUTE_UNUSED) {
580 LOG(ERROR) << "called noop";
581 }
582
TEST(logging,LOG_FATAL_NOOP_ABORTER)583 TEST(logging, LOG_FATAL_NOOP_ABORTER) {
584 CapturedStderr cap;
585 {
586 android::base::SetAborter(NoopAborter);
587
588 android::base::ScopedLogSeverity sls(android::base::ERROR);
589 LOG(FATAL) << "foobar";
590 cap.Stop();
591
592 android::base::SetAborter(android::base::DefaultAborter);
593 }
594 std::string output = cap.str();
595 ASSERT_NO_FATAL_FAILURE(CheckMessage(output, android::base::FATAL, "foobar"));
596 ASSERT_NO_FATAL_FAILURE(CheckMessage(output, android::base::ERROR, "called noop"));
597
598 ASSERT_DEATH({SuppressAbortUI(); LOG(FATAL) << "foobar";}, "foobar");
599 }
600
601 struct CountLineAborter {
CountLineAborterFunctionCountLineAborter602 static void CountLineAborterFunction(const char* msg) {
603 while (*msg != 0) {
604 if (*msg == '\n') {
605 newline_count++;
606 }
607 msg++;
608 }
609 }
610 static size_t newline_count;
611 };
612 size_t CountLineAborter::newline_count = 0;
613
TEST(logging,LOG_FATAL_ABORTER_MESSAGE)614 TEST(logging, LOG_FATAL_ABORTER_MESSAGE) {
615 CountLineAborter::newline_count = 0;
616 android::base::SetAborter(CountLineAborter::CountLineAborterFunction);
617
618 android::base::ScopedLogSeverity sls(android::base::ERROR);
619 CapturedStderr cap;
620 LOG(FATAL) << "foo\nbar";
621
622 EXPECT_EQ(CountLineAborter::newline_count, 1U);
623 }
624
TEST(logging,SetAborterReturnsOldFunction)625 TEST(logging, SetAborterReturnsOldFunction) {
626 // std::function is not comparable, it only supports a null check.
627 android::base::AbortFunction old_aborter;
628 EXPECT_FALSE(old_aborter);
629 old_aborter = android::base::SetAborter(android::base::DefaultAborter);
630 EXPECT_TRUE(old_aborter);
631 }
632
TestLoggingInConstructor()633 __attribute__((constructor)) void TestLoggingInConstructor() {
634 LOG(ERROR) << "foobar";
635 }
636
TEST(logging,StdioLogger)637 TEST(logging, StdioLogger) {
638 CapturedStderr cap_err;
639 CapturedStdout cap_out;
640 android::base::SetLogger(android::base::StdioLogger);
641 LOG(INFO) << "out";
642 LOG(ERROR) << "err";
643 cap_err.Stop();
644 cap_out.Stop();
645
646 // For INFO we expect just the literal "out\n".
647 ASSERT_EQ("out\n", cap_out.str());
648 // Whereas ERROR logging includes the program name.
649 ASSERT_EQ(android::base::Basename(android::base::GetExecutablePath()) + ": err\n", cap_err.str());
650 }
651
TEST(logging,SetLoggerReturnsOldFunction)652 TEST(logging, SetLoggerReturnsOldFunction) {
653 // std::function is not comparable, it only supports a null check.
654 android::base::LogFunction old_function;
655 EXPECT_FALSE(old_function);
656 old_function = android::base::SetLogger(android::base::StdioLogger);
657 EXPECT_TRUE(old_function);
658 }
659
TEST(logging,ForkSafe)660 TEST(logging, ForkSafe) {
661 #if !defined(_WIN32)
662 using namespace android::base;
663 SetLogger(
664 [&](LogId, LogSeverity, const char*, const char*, unsigned int, const char*) { sleep(3); });
665
666 auto guard = make_scope_guard([&] {
667 #ifdef __ANDROID__
668 SetLogger(LogdLogger());
669 #else
670 SetLogger(StderrLogger);
671 #endif
672 });
673
674 auto thread = std::thread([] {
675 LOG(ERROR) << "This should sleep for 3 seconds, long enough to fork another process, if there "
676 "is no intervention";
677 });
678 thread.detach();
679
680 auto pid = fork();
681 ASSERT_NE(-1, pid);
682
683 if (pid == 0) {
684 // Reset the logger, so the next message doesn't sleep().
685 SetLogger([](LogId, LogSeverity, const char*, const char*, unsigned int, const char*) {});
686 LOG(ERROR) << "This should succeed in the child, only if libbase is forksafe.";
687 _exit(EXIT_SUCCESS);
688 }
689
690 // Wait for up to 3 seconds for the child to exit.
691 int tries = 3;
692 bool found_child = false;
693 while (tries-- > 0) {
694 auto result = waitpid(pid, nullptr, WNOHANG);
695 EXPECT_NE(-1, result);
696 if (result == pid) {
697 found_child = true;
698 break;
699 }
700 sleep(1);
701 }
702
703 EXPECT_TRUE(found_child);
704
705 // Kill the child if it did not exit.
706 if (!found_child) {
707 kill(pid, SIGKILL);
708 }
709 #endif
710 }
711