| 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)
|
| 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
|
|
|