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