• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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