Chromium Code Reviews| Index: base/logging_unittest.cc |
| diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc |
| index f41cce2f43b390fa9603a14f3f689fe87d0dcb33..6a18a109ff71efe6f530491786696e56d984d4fe 100644 |
| --- a/base/logging_unittest.cc |
| +++ b/base/logging_unittest.cc |
| @@ -3,6 +3,7 @@ |
| // found in the LICENSE file. |
| #include "base/compiler_specific.h" |
| +#include "base/debug/dump_without_crashing.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| @@ -16,11 +17,11 @@ namespace { |
| using ::testing::Return; |
| // Needs to be global since log assert handlers can't maintain state. |
| -int log_sink_call_count = 0; |
| +int g_log_sink_call_count = 0; |
| #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG) |
| void LogSink(const std::string& str) { |
| - ++log_sink_call_count; |
| + ++g_log_sink_call_count; |
| } |
| #endif |
| @@ -33,7 +34,7 @@ class LogStateSaver { |
| ~LogStateSaver() { |
| SetMinLogLevel(old_min_log_level_); |
| SetLogAssertHandler(NULL); |
| - log_sink_call_count = 0; |
| + g_log_sink_call_count = 0; |
| } |
| private: |
| @@ -86,10 +87,12 @@ TEST_F(LoggingTest, BasicLogging) { |
| } |
| TEST_F(LoggingTest, LogIsOn) { |
| -#if defined(NDEBUG) |
| - const bool kDfatalIsFatal = false; |
| +#if defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
| + const bool kDfatalIsActive = true; |
| +#elif defined(NDEBUG) |
| + const bool kDfatalIsActive = false; |
| #else // defined(NDEBUG) |
| - const bool kDfatalIsFatal = true; |
| + const bool kDfatalIsActive = true; |
| #endif // defined(NDEBUG) |
| SetMinLogLevel(LOG_INFO); |
| @@ -119,7 +122,9 @@ TEST_F(LoggingTest, LogIsOn) { |
| EXPECT_FALSE(LOG_IS_ON(WARNING)); |
| EXPECT_FALSE(LOG_IS_ON(ERROR)); |
| EXPECT_TRUE(LOG_IS_ON(FATAL)); |
| - EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL)); |
| + EXPECT_EQ(kDfatalIsActive, LOG_IS_ON(DFATAL)); |
| + |
| + EXPECT_EQ(DCHECK_IS_ON() != 0, LOG_IS_ON(DCHECK)); |
| } |
| TEST_F(LoggingTest, LoggingIsLazyBySeverity) { |
| @@ -191,7 +196,7 @@ TEST_F(LoggingTest, CheckStreamsAreLazy) { |
| #endif |
| TEST_F(LoggingTest, DebugLoggingReleaseBehavior) { |
| -#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |
| +#if DCHECK_IS_ON() |
| int debug_only_variable = 1; |
| #endif |
| // These should avoid emitting references to |debug_only_variable| |
| @@ -217,6 +222,7 @@ TEST_F(LoggingTest, DcheckStreamsAreLazy) { |
| #endif |
| } |
| +#if !defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
|
Wez
2017/01/15 01:18:43
gab, danakj: I've completely disabled this test, s
|
| void DcheckEmptyFunction1() { |
| // Provide a body so that Release builds do not cause the compiler to |
| // optimize DcheckEmptyFunction1 and DcheckEmptyFunction2 as a single |
| @@ -242,33 +248,33 @@ TEST_F(LoggingTest, Dcheck) { |
| EXPECT_TRUE(DLOG_IS_ON(DCHECK)); |
| #endif |
| - EXPECT_EQ(0, log_sink_call_count); |
| + EXPECT_EQ(0, g_log_sink_call_count); |
| DCHECK(false); |
| - EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count); |
| + EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count); |
| DPCHECK(false); |
| - EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count); |
| + EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count); |
| DCHECK_EQ(0, 1); |
| - EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count); |
| + EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, g_log_sink_call_count); |
| // Test DCHECK on std::nullptr_t |
| - log_sink_call_count = 0; |
| + g_log_sink_call_count = 0; |
| const void* p_null = nullptr; |
| const void* p_not_null = &p_null; |
| DCHECK_EQ(p_null, nullptr); |
| DCHECK_EQ(nullptr, p_null); |
| DCHECK_NE(p_not_null, nullptr); |
| DCHECK_NE(nullptr, p_not_null); |
| - EXPECT_EQ(0, log_sink_call_count); |
| + EXPECT_EQ(0, g_log_sink_call_count); |
| // Test DCHECK on a scoped enum. |
| enum class Animal { DOG, CAT }; |
| DCHECK_EQ(Animal::DOG, Animal::DOG); |
| - EXPECT_EQ(0, log_sink_call_count); |
| + EXPECT_EQ(0, g_log_sink_call_count); |
| DCHECK_EQ(Animal::DOG, Animal::CAT); |
| - EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count); |
| + EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count); |
| // Test DCHECK on functions and function pointers. |
| - log_sink_call_count = 0; |
| + g_log_sink_call_count = 0; |
| struct MemberFunctions { |
| void MemberFunction1() { |
| // See the comment in DcheckEmptyFunction1(). |
| @@ -282,16 +288,17 @@ TEST_F(LoggingTest, Dcheck) { |
| void (*fp2)() = DcheckEmptyFunction2; |
| void (*fp3)() = DcheckEmptyFunction1; |
| DCHECK_EQ(fp1, fp3); |
| - EXPECT_EQ(0, log_sink_call_count); |
| + EXPECT_EQ(0, g_log_sink_call_count); |
| DCHECK_EQ(mp1, &MemberFunctions::MemberFunction1); |
| - EXPECT_EQ(0, log_sink_call_count); |
| + EXPECT_EQ(0, g_log_sink_call_count); |
| DCHECK_EQ(mp2, &MemberFunctions::MemberFunction2); |
| - EXPECT_EQ(0, log_sink_call_count); |
| + EXPECT_EQ(0, g_log_sink_call_count); |
| DCHECK_EQ(fp1, fp2); |
| - EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count); |
| + EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count); |
| DCHECK_EQ(mp2, &MemberFunctions::MemberFunction1); |
| - EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count); |
| + EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count); |
| } |
| +#endif // !defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
| TEST_F(LoggingTest, DcheckReleaseBehavior) { |
| int some_variable = 1; |
| @@ -326,6 +333,37 @@ TEST_F(LoggingTest, CheckEqStatements) { |
| CHECK_EQ(false, true); // Unreached. |
| } |
| +namespace { |
| + |
| +int g_fake_dump_without_crashing_count = 0; |
| +void FakeDumpWithoutCrashing() { |
| + g_fake_dump_without_crashing_count++; |
| +} |
| + |
| +} // namespace |
| + |
| +TEST_F(LoggingTest, LogMessageDump) { |
| + // Replace the dump-without-crashing function, to test. |
| + base::debug::SetDumpWithoutCrashingFunction(&FakeDumpWithoutCrashing); |
| + |
| + // LOG_DUMP is an internal severity level for use by dump-on-DCHECK, so |
| + // we must call LogMessage() directly, rather than using LOG(DUMP). |
| + LogMessage(__FILE__, __LINE__, LOG_DUMP, new std::string); |
| + EXPECT_EQ(1, g_fake_dump_without_crashing_count); |
| + LogMessage(__FILE__, __LINE__, LOG_DUMP, new std::string); |
| + EXPECT_EQ(1, g_fake_dump_without_crashing_count); |
| + |
| +#if defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
| + EXPECT_EQ(LOG_DUMP, LOG_DFATAL); |
| + EXPECT_EQ(LOG_DUMP, LOG_DCHECK); |
| +#else // defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
| + EXPECT_NE(LOG_DUMP, LOG_DFATAL); |
| + EXPECT_NE(LOG_DUMP, LOG_DCHECK); |
| +#endif // defined(DCHECK_IS_DUMP_WITHOUT_CRASH) |
| + |
| + base::debug::SetDumpWithoutCrashingFunction(nullptr); |
| +} |
| + |
| // Test that defining an operator<< for a type in a namespace doesn't prevent |
| // other code in that namespace from calling the operator<<(ostream, wstring) |
| // defined by logging.h. This can fail if operator<<(ostream, wstring) can't be |