blob: 6ebe32e432aa06374645477badb59a2b2b5fd09f [file] [log] [blame]
jeffbailey@chromium.orgeff8f002011-04-03 06:13:21 +09001// Copyright (c) 2011 The Chromium Authors. All rights reserved.
akalin@chromium.orga88579b2010-10-02 08:02:36 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
6#include "base/logging.h"
7
8#include "testing/gmock/include/gmock/gmock.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace logging {
12
13namespace {
14
15using ::testing::Return;
16
akalin@chromium.org25cef532010-11-02 04:49:22 +090017// Needs to be global since log assert handlers can't maintain state.
18int log_sink_call_count = 0;
19
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +090020#if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG)
akalin@chromium.org25cef532010-11-02 04:49:22 +090021void LogSink(const std::string& str) {
22 ++log_sink_call_count;
23}
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +090024#endif
akalin@chromium.org25cef532010-11-02 04:49:22 +090025
akalin@chromium.orga88579b2010-10-02 08:02:36 +090026// Class to make sure any manipulations we do to the min log level are
27// contained (i.e., do not affect other unit tests).
akalin@chromium.org25cef532010-11-02 04:49:22 +090028class LogStateSaver {
akalin@chromium.orga88579b2010-10-02 08:02:36 +090029 public:
akalin@chromium.org25cef532010-11-02 04:49:22 +090030 LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {}
akalin@chromium.orga88579b2010-10-02 08:02:36 +090031
akalin@chromium.org25cef532010-11-02 04:49:22 +090032 ~LogStateSaver() {
33 SetMinLogLevel(old_min_log_level_);
34 SetLogAssertHandler(NULL);
akalin@chromium.org25cef532010-11-02 04:49:22 +090035 log_sink_call_count = 0;
36 }
akalin@chromium.orga88579b2010-10-02 08:02:36 +090037
38 private:
39 int old_min_log_level_;
40
akalin@chromium.org25cef532010-11-02 04:49:22 +090041 DISALLOW_COPY_AND_ASSIGN(LogStateSaver);
akalin@chromium.orga88579b2010-10-02 08:02:36 +090042};
43
44class LoggingTest : public testing::Test {
45 private:
akalin@chromium.org25cef532010-11-02 04:49:22 +090046 LogStateSaver log_state_saver_;
akalin@chromium.orga88579b2010-10-02 08:02:36 +090047};
48
49class MockLogSource {
50 public:
51 MOCK_METHOD0(Log, const char*());
52};
53
54TEST_F(LoggingTest, BasicLogging) {
55 MockLogSource mock_log_source;
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +090056 EXPECT_CALL(mock_log_source, Log()).Times(DEBUG_MODE ? 16 : 8).
akalin@chromium.orga88579b2010-10-02 08:02:36 +090057 WillRepeatedly(Return("log message"));
58
59 SetMinLogLevel(LOG_INFO);
60
61 EXPECT_TRUE(LOG_IS_ON(INFO));
jeffbailey@chromium.orgeff8f002011-04-03 06:13:21 +090062 // As of g++-4.5, the first argument to EXPECT_EQ cannot be a
63 // constant expression.
64 const bool kIsDebugMode = (DEBUG_MODE != 0);
mostynb@opera.com7b2ca622013-04-12 16:31:15 +090065 EXPECT_TRUE(kIsDebugMode == DLOG_IS_ON(INFO));
akalin@chromium.orga88579b2010-10-02 08:02:36 +090066 EXPECT_TRUE(VLOG_IS_ON(0));
67
68 LOG(INFO) << mock_log_source.Log();
69 LOG_IF(INFO, true) << mock_log_source.Log();
70 PLOG(INFO) << mock_log_source.Log();
71 PLOG_IF(INFO, true) << mock_log_source.Log();
72 VLOG(0) << mock_log_source.Log();
73 VLOG_IF(0, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +090074 VPLOG(0) << mock_log_source.Log();
75 VPLOG_IF(0, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +090076
77 DLOG(INFO) << mock_log_source.Log();
78 DLOG_IF(INFO, true) << mock_log_source.Log();
79 DPLOG(INFO) << mock_log_source.Log();
80 DPLOG_IF(INFO, true) << mock_log_source.Log();
81 DVLOG(0) << mock_log_source.Log();
82 DVLOG_IF(0, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +090083 DVPLOG(0) << mock_log_source.Log();
84 DVPLOG_IF(0, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +090085}
86
akalin@chromium.org434c5b62010-11-03 14:30:14 +090087TEST_F(LoggingTest, LogIsOn) {
88#if defined(NDEBUG)
89 const bool kDfatalIsFatal = false;
90#else // defined(NDEBUG)
91 const bool kDfatalIsFatal = true;
92#endif // defined(NDEBUG)
93
94 SetMinLogLevel(LOG_INFO);
95 EXPECT_TRUE(LOG_IS_ON(INFO));
96 EXPECT_TRUE(LOG_IS_ON(WARNING));
97 EXPECT_TRUE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +090098 EXPECT_TRUE(LOG_IS_ON(FATAL));
99 EXPECT_TRUE(LOG_IS_ON(DFATAL));
100
101 SetMinLogLevel(LOG_WARNING);
102 EXPECT_FALSE(LOG_IS_ON(INFO));
103 EXPECT_TRUE(LOG_IS_ON(WARNING));
104 EXPECT_TRUE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900105 EXPECT_TRUE(LOG_IS_ON(FATAL));
106 EXPECT_TRUE(LOG_IS_ON(DFATAL));
107
108 SetMinLogLevel(LOG_ERROR);
109 EXPECT_FALSE(LOG_IS_ON(INFO));
110 EXPECT_FALSE(LOG_IS_ON(WARNING));
111 EXPECT_TRUE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900112 EXPECT_TRUE(LOG_IS_ON(FATAL));
113 EXPECT_TRUE(LOG_IS_ON(DFATAL));
114
viettrungluu@chromium.org96925ac2014-06-17 21:04:23 +0900115 // LOG_IS_ON(FATAL) should always be true.
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900116 SetMinLogLevel(LOG_FATAL + 1);
117 EXPECT_FALSE(LOG_IS_ON(INFO));
118 EXPECT_FALSE(LOG_IS_ON(WARNING));
119 EXPECT_FALSE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900120 EXPECT_TRUE(LOG_IS_ON(FATAL));
mostynb@opera.com7b2ca622013-04-12 16:31:15 +0900121 EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900122}
123
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900124TEST_F(LoggingTest, LoggingIsLazy) {
125 MockLogSource mock_log_source;
126 EXPECT_CALL(mock_log_source, Log()).Times(0);
127
128 SetMinLogLevel(LOG_WARNING);
129
130 EXPECT_FALSE(LOG_IS_ON(INFO));
131 EXPECT_FALSE(DLOG_IS_ON(INFO));
132 EXPECT_FALSE(VLOG_IS_ON(1));
133
134 LOG(INFO) << mock_log_source.Log();
135 LOG_IF(INFO, false) << mock_log_source.Log();
136 PLOG(INFO) << mock_log_source.Log();
137 PLOG_IF(INFO, false) << mock_log_source.Log();
138 VLOG(1) << mock_log_source.Log();
139 VLOG_IF(1, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +0900140 VPLOG(1) << mock_log_source.Log();
141 VPLOG_IF(1, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900142
143 DLOG(INFO) << mock_log_source.Log();
144 DLOG_IF(INFO, true) << mock_log_source.Log();
145 DPLOG(INFO) << mock_log_source.Log();
146 DPLOG_IF(INFO, true) << mock_log_source.Log();
147 DVLOG(1) << mock_log_source.Log();
148 DVLOG_IF(1, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +0900149 DVPLOG(1) << mock_log_source.Log();
150 DVPLOG_IF(1, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900151}
152
akalin@chromium.org1fcfcd42011-12-16 15:01:23 +0900153// Official builds have CHECKs directly call BreakDebugger.
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900154#if !defined(OFFICIAL_BUILD)
akalin@chromium.org1fcfcd42011-12-16 15:01:23 +0900155
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900156TEST_F(LoggingTest, CheckStreamsAreLazy) {
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900157 MockLogSource mock_log_source, uncalled_mock_log_source;
158 EXPECT_CALL(mock_log_source, Log()).Times(8).
159 WillRepeatedly(Return("check message"));
160 EXPECT_CALL(uncalled_mock_log_source, Log()).Times(0);
161
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900162 SetLogAssertHandler(&LogSink);
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900163
164 CHECK(mock_log_source.Log()) << uncalled_mock_log_source.Log();
165 PCHECK(!mock_log_source.Log()) << mock_log_source.Log();
166 CHECK_EQ(mock_log_source.Log(), mock_log_source.Log())
167 << uncalled_mock_log_source.Log();
168 CHECK_NE(mock_log_source.Log(), mock_log_source.Log())
169 << mock_log_source.Log();
170}
171
akalin@chromium.org1fcfcd42011-12-16 15:01:23 +0900172#endif
173
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900174TEST_F(LoggingTest, DebugLoggingReleaseBehavior) {
175#if !defined(NDEBUG)
176 int debug_only_variable = 1;
177#endif
178 // These should avoid emitting references to |debug_only_variable|
179 // in release mode.
180 DLOG_IF(INFO, debug_only_variable) << "test";
181 DLOG_ASSERT(debug_only_variable) << "test";
182 DPLOG_IF(INFO, debug_only_variable) << "test";
183 DVLOG_IF(1, debug_only_variable) << "test";
184}
185
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900186TEST_F(LoggingTest, DcheckStreamsAreLazy) {
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900187 MockLogSource mock_log_source;
188 EXPECT_CALL(mock_log_source, Log()).Times(0);
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900189#if DCHECK_IS_ON
190 DCHECK(true) << mock_log_source.Log();
191 DCHECK_EQ(0, 0) << mock_log_source.Log();
192#else
193 DCHECK(mock_log_source.Log()) << mock_log_source.Log();
194 DPCHECK(mock_log_source.Log()) << mock_log_source.Log();
195 DCHECK_EQ(0, 0) << mock_log_source.Log();
196 DCHECK_EQ(mock_log_source.Log(), static_cast<const char*>(NULL))
197 << mock_log_source.Log();
198#endif
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900199}
200
akalin@chromium.org25cef532010-11-02 04:49:22 +0900201TEST_F(LoggingTest, Dcheck) {
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900202#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
203 // Release build.
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900204 EXPECT_FALSE(DCHECK_IS_ON);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900205 EXPECT_FALSE(DLOG_IS_ON(DCHECK));
nsylvain@chromium.org675aad32011-09-21 05:59:01 +0900206#elif defined(NDEBUG) && defined(DCHECK_ALWAYS_ON)
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900207 // Release build with real DCHECKS.
nsylvain@chromium.org675aad32011-09-21 05:59:01 +0900208 SetLogAssertHandler(&LogSink);
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900209 EXPECT_TRUE(DCHECK_IS_ON);
nsylvain@chromium.org675aad32011-09-21 05:59:01 +0900210 EXPECT_FALSE(DLOG_IS_ON(DCHECK));
akalin@chromium.org25cef532010-11-02 04:49:22 +0900211#else
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900212 // Debug build.
akalin@chromium.orgfaed5f82011-01-11 10:03:36 +0900213 SetLogAssertHandler(&LogSink);
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900214 EXPECT_TRUE(DCHECK_IS_ON);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900215 EXPECT_TRUE(DLOG_IS_ON(DCHECK));
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900216#endif
akalin@chromium.org25cef532010-11-02 04:49:22 +0900217
218 EXPECT_EQ(0, log_sink_call_count);
219 DCHECK(false);
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900220 EXPECT_EQ(DCHECK_IS_ON ? 1 : 0, log_sink_call_count);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900221 DPCHECK(false);
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900222 EXPECT_EQ(DCHECK_IS_ON ? 2 : 0, log_sink_call_count);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900223 DCHECK_EQ(0, 1);
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900224 EXPECT_EQ(DCHECK_IS_ON ? 3 : 0, log_sink_call_count);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900225}
226
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900227TEST_F(LoggingTest, DcheckReleaseBehavior) {
228 int some_variable = 1;
229 // These should still reference |some_variable| so we don't get
230 // unused variable warnings.
231 DCHECK(some_variable) << "test";
232 DPCHECK(some_variable) << "test";
233 DCHECK_EQ(some_variable, 1) << "test";
234}
235
jyasskin@chromium.orgf01cfba2014-07-09 08:03:06 +0900236// Test that defining an operator<< for a type in a namespace doesn't prevent
237// other code in that namespace from calling the operator<<(ostream, wstring)
238// defined by logging.h. This can fail if operator<<(ostream, wstring) can't be
239// found by ADL, since defining another operator<< prevents name lookup from
240// looking in the global namespace.
241namespace nested_test {
242 class Streamable {};
243 ALLOW_UNUSED std::ostream& operator<<(std::ostream& out, const Streamable&) {
244 return out << "Streamable";
245 }
246 TEST_F(LoggingTest, StreamingWstringFindsCorrectOperator) {
247 std::wstring wstr = L"Hello World";
248 std::ostringstream ostr;
249 ostr << wstr;
250 EXPECT_EQ("Hello World", ostr.str());
251 }
252} // namespace nested_test
253
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900254} // namespace
255
256} // namespace logging