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 <regex>
26 #include <string>
27
28 #include "android-base/file.h"
29 #include "android-base/stringprintf.h"
30 #include "android-base/test_utils.h"
31
32 #include <gtest/gtest.h>
33
34 #ifdef __ANDROID__
35 #define HOST_TEST(suite, name) TEST(suite, DISABLED_ ## name)
36 #else
37 #define HOST_TEST(suite, name) TEST(suite, name)
38 #endif
39
40 #if defined(_WIN32)
ExitSignalAbortHandler(int)41 static void ExitSignalAbortHandler(int) {
42 _exit(3);
43 }
44 #endif
45
SuppressAbortUI()46 static void SuppressAbortUI() {
47 #if defined(_WIN32)
48 // We really just want to call _set_abort_behavior(0, _CALL_REPORTFAULT) to
49 // suppress the Windows Error Reporting dialog box, but that API is not
50 // available in the OS-supplied C Runtime, msvcrt.dll, that we currently
51 // use (it is available in the Visual Studio C runtime).
52 //
53 // Instead, we setup a SIGABRT handler, which is called in abort() right
54 // before calling Windows Error Reporting. In the handler, we exit the
55 // process just like abort() does.
56 ASSERT_NE(SIG_ERR, signal(SIGABRT, ExitSignalAbortHandler));
57 #endif
58 }
59
TEST(logging,CHECK)60 TEST(logging, CHECK) {
61 ASSERT_DEATH({SuppressAbortUI(); CHECK(false);}, "Check failed: false ");
62 CHECK(true);
63
64 ASSERT_DEATH({SuppressAbortUI(); CHECK_EQ(0, 1);}, "Check failed: 0 == 1 ");
65 CHECK_EQ(0, 0);
66
67 ASSERT_DEATH({SuppressAbortUI(); CHECK_STREQ("foo", "bar");},
68 R"(Check failed: "foo" == "bar")");
69 CHECK_STREQ("foo", "foo");
70
71 // Test whether CHECK() and CHECK_STREQ() have a dangling if with no else.
72 bool flag = false;
73 if (true)
74 CHECK(true);
75 else
76 flag = true;
77 EXPECT_FALSE(flag) << "CHECK macro probably has a dangling if with no else";
78
79 flag = false;
80 if (true)
81 CHECK_STREQ("foo", "foo");
82 else
83 flag = true;
84 EXPECT_FALSE(flag) << "CHECK_STREQ probably has a dangling if with no else";
85 }
86
TEST(logging,DCHECK)87 TEST(logging, DCHECK) {
88 if (android::base::kEnableDChecks) {
89 ASSERT_DEATH({SuppressAbortUI(); DCHECK(false);}, "DCheck failed: false ");
90 }
91 DCHECK(true);
92
93 if (android::base::kEnableDChecks) {
94 ASSERT_DEATH({SuppressAbortUI(); DCHECK_EQ(0, 1);}, "DCheck failed: 0 == 1 ");
95 }
96 DCHECK_EQ(0, 0);
97
98 if (android::base::kEnableDChecks) {
99 ASSERT_DEATH({SuppressAbortUI(); DCHECK_STREQ("foo", "bar");},
100 R"(DCheck failed: "foo" == "bar")");
101 }
102 DCHECK_STREQ("foo", "foo");
103
104 // No testing whether we have a dangling else, possibly. That's inherent to the if (constexpr)
105 // setup we intentionally chose to force type-checks of debug code even in release builds (so
106 // we don't get more bit-rot).
107 }
108
109
110 #define CHECK_WOULD_LOG_DISABLED(severity) \
111 static_assert(android::base::severity < android::base::FATAL, "Bad input"); \
112 for (size_t i = static_cast<size_t>(android::base::severity) + 1; \
113 i <= static_cast<size_t>(android::base::FATAL); \
114 ++i) { \
115 { \
116 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
117 EXPECT_FALSE(WOULD_LOG(severity)) << i; \
118 } \
119 { \
120 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
121 EXPECT_FALSE(WOULD_LOG(::android::base::severity)) << i; \
122 } \
123 } \
124
125 #define CHECK_WOULD_LOG_ENABLED(severity) \
126 for (size_t i = static_cast<size_t>(android::base::VERBOSE); \
127 i <= static_cast<size_t>(android::base::severity); \
128 ++i) { \
129 { \
130 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
131 EXPECT_TRUE(WOULD_LOG(severity)) << i; \
132 } \
133 { \
134 android::base::ScopedLogSeverity sls2(static_cast<android::base::LogSeverity>(i)); \
135 EXPECT_TRUE(WOULD_LOG(::android::base::severity)) << i; \
136 } \
137 } \
138
TEST(logging,WOULD_LOG_FATAL)139 TEST(logging, WOULD_LOG_FATAL) {
140 CHECK_WOULD_LOG_ENABLED(FATAL);
141 }
142
TEST(logging,WOULD_LOG_FATAL_WITHOUT_ABORT_disabled)143 TEST(logging, WOULD_LOG_FATAL_WITHOUT_ABORT_disabled) {
144 CHECK_WOULD_LOG_DISABLED(FATAL_WITHOUT_ABORT);
145 }
146
TEST(logging,WOULD_LOG_FATAL_WITHOUT_ABORT_enabled)147 TEST(logging, WOULD_LOG_FATAL_WITHOUT_ABORT_enabled) {
148 CHECK_WOULD_LOG_ENABLED(FATAL_WITHOUT_ABORT);
149 }
150
TEST(logging,WOULD_LOG_ERROR_disabled)151 TEST(logging, WOULD_LOG_ERROR_disabled) {
152 CHECK_WOULD_LOG_DISABLED(ERROR);
153 }
154
TEST(logging,WOULD_LOG_ERROR_enabled)155 TEST(logging, WOULD_LOG_ERROR_enabled) {
156 CHECK_WOULD_LOG_ENABLED(ERROR);
157 }
158
TEST(logging,WOULD_LOG_WARNING_disabled)159 TEST(logging, WOULD_LOG_WARNING_disabled) {
160 CHECK_WOULD_LOG_DISABLED(WARNING);
161 }
162
TEST(logging,WOULD_LOG_WARNING_enabled)163 TEST(logging, WOULD_LOG_WARNING_enabled) {
164 CHECK_WOULD_LOG_ENABLED(WARNING);
165 }
166
TEST(logging,WOULD_LOG_INFO_disabled)167 TEST(logging, WOULD_LOG_INFO_disabled) {
168 CHECK_WOULD_LOG_DISABLED(INFO);
169 }
170
TEST(logging,WOULD_LOG_INFO_enabled)171 TEST(logging, WOULD_LOG_INFO_enabled) {
172 CHECK_WOULD_LOG_ENABLED(INFO);
173 }
174
TEST(logging,WOULD_LOG_DEBUG_disabled)175 TEST(logging, WOULD_LOG_DEBUG_disabled) {
176 CHECK_WOULD_LOG_DISABLED(DEBUG);
177 }
178
TEST(logging,WOULD_LOG_DEBUG_enabled)179 TEST(logging, WOULD_LOG_DEBUG_enabled) {
180 CHECK_WOULD_LOG_ENABLED(DEBUG);
181 }
182
TEST(logging,WOULD_LOG_VERBOSE_disabled)183 TEST(logging, WOULD_LOG_VERBOSE_disabled) {
184 CHECK_WOULD_LOG_DISABLED(VERBOSE);
185 }
186
TEST(logging,WOULD_LOG_VERBOSE_enabled)187 TEST(logging, WOULD_LOG_VERBOSE_enabled) {
188 CHECK_WOULD_LOG_ENABLED(VERBOSE);
189 }
190
191 #undef CHECK_WOULD_LOG_DISABLED
192 #undef CHECK_WOULD_LOG_ENABLED
193
194
make_log_pattern(android::base::LogSeverity severity,const char * message)195 static std::string make_log_pattern(android::base::LogSeverity severity,
196 const char* message) {
197 static const char log_characters[] = "VDIWEFF";
198 static_assert(arraysize(log_characters) - 1 == android::base::FATAL + 1,
199 "Mismatch in size of log_characters and values in LogSeverity");
200 char log_char = log_characters[severity];
201 std::string holder(__FILE__);
202 return android::base::StringPrintf(
203 "%c \\d+-\\d+ \\d+:\\d+:\\d+ \\s*\\d+ \\s*\\d+ %s:\\d+] %s",
204 log_char, basename(&holder[0]), message);
205 }
206
CheckMessage(const CapturedStderr & cap,android::base::LogSeverity severity,const char * expected)207 static void CheckMessage(const CapturedStderr& cap,
208 android::base::LogSeverity severity, const char* expected) {
209 std::string output;
210 ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));
211 android::base::ReadFdToString(cap.fd(), &output);
212
213 // We can't usefully check the output of any of these on Windows because we
214 // don't have std::regex, but we can at least make sure we printed at least as
215 // many characters are in the log message.
216 ASSERT_GT(output.length(), strlen(expected));
217 ASSERT_NE(nullptr, strstr(output.c_str(), expected)) << output;
218
219 #if !defined(_WIN32)
220 std::regex message_regex(make_log_pattern(severity, expected));
221 ASSERT_TRUE(std::regex_search(output, message_regex)) << output;
222 #endif
223 }
224
225
226 #define CHECK_LOG_STREAM_DISABLED(severity) \
227 { \
228 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
229 CapturedStderr cap1; \
230 LOG_STREAM(severity) << "foo bar"; \
231 ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
232 } \
233 { \
234 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
235 CapturedStderr cap1; \
236 LOG_STREAM(::android::base::severity) << "foo bar"; \
237 ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
238 } \
239
240 #define CHECK_LOG_STREAM_ENABLED(severity) \
241 { \
242 android::base::ScopedLogSeverity sls2(android::base::severity); \
243 CapturedStderr cap2; \
244 LOG_STREAM(severity) << "foobar"; \
245 CheckMessage(cap2, android::base::severity, "foobar"); \
246 } \
247 { \
248 android::base::ScopedLogSeverity sls2(android::base::severity); \
249 CapturedStderr cap2; \
250 LOG_STREAM(::android::base::severity) << "foobar"; \
251 CheckMessage(cap2, android::base::severity, "foobar"); \
252 } \
253
TEST(logging,LOG_STREAM_FATAL_WITHOUT_ABORT_disabled)254 TEST(logging, LOG_STREAM_FATAL_WITHOUT_ABORT_disabled) {
255 CHECK_LOG_STREAM_DISABLED(FATAL_WITHOUT_ABORT);
256 }
257
TEST(logging,LOG_STREAM_FATAL_WITHOUT_ABORT_enabled)258 TEST(logging, LOG_STREAM_FATAL_WITHOUT_ABORT_enabled) {
259 CHECK_LOG_STREAM_ENABLED(FATAL_WITHOUT_ABORT);
260 }
261
TEST(logging,LOG_STREAM_ERROR_disabled)262 TEST(logging, LOG_STREAM_ERROR_disabled) {
263 CHECK_LOG_STREAM_DISABLED(ERROR);
264 }
265
TEST(logging,LOG_STREAM_ERROR_enabled)266 TEST(logging, LOG_STREAM_ERROR_enabled) {
267 CHECK_LOG_STREAM_ENABLED(ERROR);
268 }
269
TEST(logging,LOG_STREAM_WARNING_disabled)270 TEST(logging, LOG_STREAM_WARNING_disabled) {
271 CHECK_LOG_STREAM_DISABLED(WARNING);
272 }
273
TEST(logging,LOG_STREAM_WARNING_enabled)274 TEST(logging, LOG_STREAM_WARNING_enabled) {
275 CHECK_LOG_STREAM_ENABLED(WARNING);
276 }
277
TEST(logging,LOG_STREAM_INFO_disabled)278 TEST(logging, LOG_STREAM_INFO_disabled) {
279 CHECK_LOG_STREAM_DISABLED(INFO);
280 }
281
TEST(logging,LOG_STREAM_INFO_enabled)282 TEST(logging, LOG_STREAM_INFO_enabled) {
283 CHECK_LOG_STREAM_ENABLED(INFO);
284 }
285
TEST(logging,LOG_STREAM_DEBUG_disabled)286 TEST(logging, LOG_STREAM_DEBUG_disabled) {
287 CHECK_LOG_STREAM_DISABLED(DEBUG);
288 }
289
TEST(logging,LOG_STREAM_DEBUG_enabled)290 TEST(logging, LOG_STREAM_DEBUG_enabled) {
291 CHECK_LOG_STREAM_ENABLED(DEBUG);
292 }
293
TEST(logging,LOG_STREAM_VERBOSE_disabled)294 TEST(logging, LOG_STREAM_VERBOSE_disabled) {
295 CHECK_LOG_STREAM_DISABLED(VERBOSE);
296 }
297
TEST(logging,LOG_STREAM_VERBOSE_enabled)298 TEST(logging, LOG_STREAM_VERBOSE_enabled) {
299 CHECK_LOG_STREAM_ENABLED(VERBOSE);
300 }
301
302 #undef CHECK_LOG_STREAM_DISABLED
303 #undef CHECK_LOG_STREAM_ENABLED
304
305
306 #define CHECK_LOG_DISABLED(severity) \
307 { \
308 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
309 CapturedStderr cap1; \
310 LOG(severity) << "foo bar"; \
311 ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
312 } \
313 { \
314 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
315 CapturedStderr cap1; \
316 LOG(::android::base::severity) << "foo bar"; \
317 ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
318 } \
319
320 #define CHECK_LOG_ENABLED(severity) \
321 { \
322 android::base::ScopedLogSeverity sls2(android::base::severity); \
323 CapturedStderr cap2; \
324 LOG(severity) << "foobar"; \
325 CheckMessage(cap2, android::base::severity, "foobar"); \
326 } \
327 { \
328 android::base::ScopedLogSeverity sls2(android::base::severity); \
329 CapturedStderr cap2; \
330 LOG(::android::base::severity) << "foobar"; \
331 CheckMessage(cap2, android::base::severity, "foobar"); \
332 } \
333
TEST(logging,LOG_FATAL)334 TEST(logging, LOG_FATAL) {
335 ASSERT_DEATH({SuppressAbortUI(); LOG(FATAL) << "foobar";}, "foobar");
336 ASSERT_DEATH({SuppressAbortUI(); LOG(::android::base::FATAL) << "foobar";}, "foobar");
337 }
338
TEST(logging,LOG_FATAL_WITHOUT_ABORT_disabled)339 TEST(logging, LOG_FATAL_WITHOUT_ABORT_disabled) {
340 CHECK_LOG_DISABLED(FATAL_WITHOUT_ABORT);
341 }
342
TEST(logging,LOG_FATAL_WITHOUT_ABORT_enabled)343 TEST(logging, LOG_FATAL_WITHOUT_ABORT_enabled) {
344 CHECK_LOG_ENABLED(FATAL_WITHOUT_ABORT);
345 }
346
TEST(logging,LOG_ERROR_disabled)347 TEST(logging, LOG_ERROR_disabled) {
348 CHECK_LOG_DISABLED(ERROR);
349 }
350
TEST(logging,LOG_ERROR_enabled)351 TEST(logging, LOG_ERROR_enabled) {
352 CHECK_LOG_ENABLED(ERROR);
353 }
354
TEST(logging,LOG_WARNING_disabled)355 TEST(logging, LOG_WARNING_disabled) {
356 CHECK_LOG_DISABLED(WARNING);
357 }
358
TEST(logging,LOG_WARNING_enabled)359 TEST(logging, LOG_WARNING_enabled) {
360 CHECK_LOG_ENABLED(WARNING);
361 }
362
TEST(logging,LOG_INFO_disabled)363 TEST(logging, LOG_INFO_disabled) {
364 CHECK_LOG_DISABLED(INFO);
365 }
366
TEST(logging,LOG_INFO_enabled)367 TEST(logging, LOG_INFO_enabled) {
368 CHECK_LOG_ENABLED(INFO);
369 }
370
TEST(logging,LOG_DEBUG_disabled)371 TEST(logging, LOG_DEBUG_disabled) {
372 CHECK_LOG_DISABLED(DEBUG);
373 }
374
TEST(logging,LOG_DEBUG_enabled)375 TEST(logging, LOG_DEBUG_enabled) {
376 CHECK_LOG_ENABLED(DEBUG);
377 }
378
TEST(logging,LOG_VERBOSE_disabled)379 TEST(logging, LOG_VERBOSE_disabled) {
380 CHECK_LOG_DISABLED(VERBOSE);
381 }
382
TEST(logging,LOG_VERBOSE_enabled)383 TEST(logging, LOG_VERBOSE_enabled) {
384 CHECK_LOG_ENABLED(VERBOSE);
385 }
386
387 #undef CHECK_LOG_DISABLED
388 #undef CHECK_LOG_ENABLED
389
390
TEST(logging,LOG_complex_param)391 TEST(logging, LOG_complex_param) {
392 #define CHECK_LOG_COMBINATION(use_scoped_log_severity_info, use_logging_severity_info) \
393 { \
394 android::base::ScopedLogSeverity sls( \
395 (use_scoped_log_severity_info) ? ::android::base::INFO : ::android::base::WARNING); \
396 CapturedStderr cap; \
397 LOG((use_logging_severity_info) ? ::android::base::INFO : ::android::base::WARNING) \
398 << "foobar"; \
399 if ((use_scoped_log_severity_info) || !(use_logging_severity_info)) { \
400 CheckMessage(cap, \
401 (use_logging_severity_info) ? ::android::base::INFO : ::android::base::WARNING, \
402 "foobar"); \
403 } else { \
404 ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_CUR)); \
405 } \
406 }
407
408 CHECK_LOG_COMBINATION(false,false);
409 CHECK_LOG_COMBINATION(false,true);
410 CHECK_LOG_COMBINATION(true,false);
411 CHECK_LOG_COMBINATION(true,true);
412
413 #undef CHECK_LOG_COMBINATION
414 }
415
416
TEST(logging,LOG_does_not_clobber_errno)417 TEST(logging, LOG_does_not_clobber_errno) {
418 CapturedStderr cap;
419 errno = 12345;
420 LOG(INFO) << (errno = 67890);
421 EXPECT_EQ(12345, errno) << "errno was not restored";
422
423 CheckMessage(cap, android::base::INFO, "67890");
424 }
425
TEST(logging,PLOG_does_not_clobber_errno)426 TEST(logging, PLOG_does_not_clobber_errno) {
427 CapturedStderr cap;
428 errno = 12345;
429 PLOG(INFO) << (errno = 67890);
430 EXPECT_EQ(12345, errno) << "errno was not restored";
431
432 CheckMessage(cap, android::base::INFO, "67890");
433 }
434
TEST(logging,LOG_does_not_have_dangling_if)435 TEST(logging, LOG_does_not_have_dangling_if) {
436 CapturedStderr cap; // So the logging below has no side-effects.
437
438 // Do the test two ways: once where we hypothesize that LOG()'s if
439 // will evaluate to true (when severity is high enough) and once when we
440 // expect it to evaluate to false (when severity is not high enough).
441 bool flag = false;
442 if (true)
443 LOG(INFO) << "foobar";
444 else
445 flag = true;
446
447 EXPECT_FALSE(flag) << "LOG macro probably has a dangling if with no else";
448
449 flag = false;
450 if (true)
451 LOG(VERBOSE) << "foobar";
452 else
453 flag = true;
454
455 EXPECT_FALSE(flag) << "LOG macro probably has a dangling if with no else";
456 }
457
458 #define CHECK_PLOG_DISABLED(severity) \
459 { \
460 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
461 CapturedStderr cap1; \
462 PLOG(severity) << "foo bar"; \
463 ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
464 } \
465 { \
466 android::base::ScopedLogSeverity sls1(android::base::FATAL); \
467 CapturedStderr cap1; \
468 PLOG(severity) << "foo bar"; \
469 ASSERT_EQ(0, lseek(cap1.fd(), 0, SEEK_CUR)); \
470 } \
471
472 #define CHECK_PLOG_ENABLED(severity) \
473 { \
474 android::base::ScopedLogSeverity sls2(android::base::severity); \
475 CapturedStderr cap2; \
476 errno = ENOENT; \
477 PLOG(severity) << "foobar"; \
478 CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
479 } \
480 { \
481 android::base::ScopedLogSeverity sls2(android::base::severity); \
482 CapturedStderr cap2; \
483 errno = ENOENT; \
484 PLOG(severity) << "foobar"; \
485 CheckMessage(cap2, android::base::severity, "foobar: No such file or directory"); \
486 } \
487
TEST(logging,PLOG_FATAL)488 TEST(logging, PLOG_FATAL) {
489 ASSERT_DEATH({SuppressAbortUI(); PLOG(FATAL) << "foobar";}, "foobar");
490 ASSERT_DEATH({SuppressAbortUI(); PLOG(::android::base::FATAL) << "foobar";}, "foobar");
491 }
492
TEST(logging,PLOG_FATAL_WITHOUT_ABORT_disabled)493 TEST(logging, PLOG_FATAL_WITHOUT_ABORT_disabled) {
494 CHECK_PLOG_DISABLED(FATAL_WITHOUT_ABORT);
495 }
496
TEST(logging,PLOG_FATAL_WITHOUT_ABORT_enabled)497 TEST(logging, PLOG_FATAL_WITHOUT_ABORT_enabled) {
498 CHECK_PLOG_ENABLED(FATAL_WITHOUT_ABORT);
499 }
500
TEST(logging,PLOG_ERROR_disabled)501 TEST(logging, PLOG_ERROR_disabled) {
502 CHECK_PLOG_DISABLED(ERROR);
503 }
504
TEST(logging,PLOG_ERROR_enabled)505 TEST(logging, PLOG_ERROR_enabled) {
506 CHECK_PLOG_ENABLED(ERROR);
507 }
508
TEST(logging,PLOG_WARNING_disabled)509 TEST(logging, PLOG_WARNING_disabled) {
510 CHECK_PLOG_DISABLED(WARNING);
511 }
512
TEST(logging,PLOG_WARNING_enabled)513 TEST(logging, PLOG_WARNING_enabled) {
514 CHECK_PLOG_ENABLED(WARNING);
515 }
516
TEST(logging,PLOG_INFO_disabled)517 TEST(logging, PLOG_INFO_disabled) {
518 CHECK_PLOG_DISABLED(INFO);
519 }
520
TEST(logging,PLOG_INFO_enabled)521 TEST(logging, PLOG_INFO_enabled) {
522 CHECK_PLOG_ENABLED(INFO);
523 }
524
TEST(logging,PLOG_DEBUG_disabled)525 TEST(logging, PLOG_DEBUG_disabled) {
526 CHECK_PLOG_DISABLED(DEBUG);
527 }
528
TEST(logging,PLOG_DEBUG_enabled)529 TEST(logging, PLOG_DEBUG_enabled) {
530 CHECK_PLOG_ENABLED(DEBUG);
531 }
532
TEST(logging,PLOG_VERBOSE_disabled)533 TEST(logging, PLOG_VERBOSE_disabled) {
534 CHECK_PLOG_DISABLED(VERBOSE);
535 }
536
TEST(logging,PLOG_VERBOSE_enabled)537 TEST(logging, PLOG_VERBOSE_enabled) {
538 CHECK_PLOG_ENABLED(VERBOSE);
539 }
540
541 #undef CHECK_PLOG_DISABLED
542 #undef CHECK_PLOG_ENABLED
543
544
TEST(logging,UNIMPLEMENTED)545 TEST(logging, UNIMPLEMENTED) {
546 std::string expected = android::base::StringPrintf("%s unimplemented ", __PRETTY_FUNCTION__);
547
548 CapturedStderr cap;
549 errno = ENOENT;
550 UNIMPLEMENTED(ERROR);
551 CheckMessage(cap, android::base::ERROR, expected.c_str());
552 }
553
NoopAborter(const char * msg ATTRIBUTE_UNUSED)554 static void NoopAborter(const char* msg ATTRIBUTE_UNUSED) {
555 LOG(ERROR) << "called noop";
556 }
557
TEST(logging,LOG_FATAL_NOOP_ABORTER)558 TEST(logging, LOG_FATAL_NOOP_ABORTER) {
559 {
560 android::base::SetAborter(NoopAborter);
561
562 android::base::ScopedLogSeverity sls(android::base::ERROR);
563 CapturedStderr cap;
564 LOG(FATAL) << "foobar";
565 CheckMessage(cap, android::base::FATAL, "foobar");
566 CheckMessage(cap, android::base::ERROR, "called noop");
567
568 android::base::SetAborter(android::base::DefaultAborter);
569 }
570
571 ASSERT_DEATH({SuppressAbortUI(); LOG(FATAL) << "foobar";}, "foobar");
572 }
573
574 struct CountLineAborter {
CountLineAborterFunctionCountLineAborter575 static void CountLineAborterFunction(const char* msg) {
576 while (*msg != 0) {
577 if (*msg == '\n') {
578 newline_count++;
579 }
580 msg++;
581 }
582 }
583 static size_t newline_count;
584 };
585 size_t CountLineAborter::newline_count = 0;
586
TEST(logging,LOG_FATAL_ABORTER_MESSAGE)587 TEST(logging, LOG_FATAL_ABORTER_MESSAGE) {
588 CountLineAborter::newline_count = 0;
589 android::base::SetAborter(CountLineAborter::CountLineAborterFunction);
590
591 android::base::ScopedLogSeverity sls(android::base::ERROR);
592 CapturedStderr cap;
593 LOG(FATAL) << "foo\nbar";
594
595 EXPECT_EQ(CountLineAborter::newline_count, 1U + 1U); // +1 for final '\n'.
596 }
597
TestLoggingInConstructor()598 __attribute__((constructor)) void TestLoggingInConstructor() {
599 LOG(ERROR) << "foobar";
600 }
601